在firebase

时间:2017-05-30 11:15:07

标签: ios swift firebase firebase-realtime-database firebase-authentication

这是我的iOS应用程序的情况(我使用的是swift 3.0和firebase)。

我有一个登录屏幕,用户可以使用Firebase的Auth通过电子邮件登录。为此,我使用此代码:

    @IBAction func signInButtonPressed(_ sender: UIButton)
{


    if let email = emailField.text, let password = passwordField.text
    {
      //  FIRDatabase.database().reference().child("users").child(self.emailField.text!).observeSingleEvent(of: .value, with: {(userEmail) in
       // FIRAuth.auth()?.signIn(withEmail: email, password: password)

        FIRAuth.auth()?.signIn(withEmail: email, password: password)
        {
            (user, error) in

            if let error = error
            {
                let alertController = UIAlertController(title: "Login or password incorrect", message:
                    "", preferredStyle: UIAlertControllerStyle.alert)
                alertController.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default,handler: nil))

                self.present(alertController, animated: true, completion: nil)                }
            else
            {
                print("AUTH: EMAIL AUTH SUCCESSFUL")

                User.currentUserId = user?.uid
                User.startTrackingCurrentUser()
                self.performSegue(withIdentifier: "ToFeed", sender: nil)
            }
        }
    }
}

哪种方法完美无缺!

我想要实现的目标是通过用户名登录用户。 为此,我认为最好的事情是在识别用户是否存在时,发送电子邮件值 - 从数据库中提取数据。

我的数据库配置正确,并获取auth系统,如:

--name of db
----posts
----users
------username
------email
------id

通过以下方式在文本字段中输入正确的用户名时,用户可以在我的控制台中识别:

@IBAction func textFieldEditingDidChange(_ sender: Any) {
    FIRDatabase.database().reference().child("users").child(self.emailField.text!).observeSingleEvent(of: .value, with: {(email) in

    if let userDict = email.value as? [String:AnyObject]{
        for each in userDict{
            let email = each.1 as! String
        }
    }

    if email.exists(){

        print(email)

    }else{

        print("USER NOT EXIST")

    }

})

}

当用户名写正确时,我在控制台中显示如下:

Snap (myuser) {
username = myuser;
email = "myemail@email.com";
id = 8mbwXUMe0Ye4ip2mhhvEySxmxiI5;

}

为此我一直关注这个帖子:

Sign In by UserName : Firebase,Swift

从现在开始,如何提交,使用snap中的电子邮件值而不是用户名才能登录?我无法完成这项工作,我已经为此工作了一个星期。 。

任何帮助都会很棒!我是从iOS Dev开始的。

非常感谢!

---编辑 -

现在我只能通过以下方式在我的控制台中尝试打印电子邮件:

IBAction func textFieldEditingDidChange(_ sender: Any) {


    FIRDatabase.database().reference().child("users").child(self.emailField.text!).observeSingleEvent(of: .value, with: {(email) in

        if let userDict = email.value as? [String:AnyObject]{
   print(email)

        }

        if email.exists(){


        }else{

            print("USER NOT EXIST")

        }

    })
}

但仍在寻找如何传递价值?

2 个答案:

答案 0 :(得分:0)

您应该从email获取此snapshot并在signIn函数中使用它:

FIRAuth.auth()!.signIn(withEmail: email, // your fetched email
                         password: userPassword.text!) { // userPassword is UITextField
                          user, error in
                          if error != nil {
                             // here process your error like
                             self.errorLabel.text = "Wrong login or password!"
                             print("\(String(describing: error?.localizedDescription))")
                          } else {
                             // you have signed in. Go to next controller
                             self.performSegue(withIdentifier: "fromLoggedInToTabBar", sender: self)
                          }
  }

希望有所帮助

答案 1 :(得分:0)

我想强调,强烈建议不要创建用户名登录系统!

让我们从用户节点开始

user_email_lookup
  johnny_unsecure: "johnny@dontdothis.com"
  fred_stolendata: "fred@exposednodes.com"

user_email_lookup节点将提供用户输入的用户名与Firebase中经过身份验证的用户的电子邮件地址之间的链接。此节点需要具有允许任何人访问它的规则 - 这是必要的,因为该节点上的查询需要由未经身份验证的用户完成。还有另一个结构选项

{
    "rules": {
        ".read": true,
        ".write": true
    }
}

但它会使管理用户名和/或电子邮件更改变得更加困难,因此不推荐使用。

(再次,不要这样做,这是不好的形式)

以下是需要应用user_email_lookup

的基本规则
func beginLogin() {
    let userName = "johnny_unsecure" //from the userNameField.text
    let password = "my_password" // from the passwordField.text

    let lookupRef = self.ref.child("user_email_lookup")
    let queryRef = lookupRef.queryOrdered(byChild: "user_name").queryEqual(toValue: userName)

    queryRef.observeSingleEvent(of: .childAdded, with: { snapshot in
        let dict = snapshot.value as! [String: Any]
        let email = dict["email"] as! String
        self.logUserIn(email: email, password: password)
    })
}


func logUserIn(email: String, password: String) {

    Auth.auth().signIn(withEmail: email, password: password, completion: { (user, error) in 
        if error != nil {
            let err = error?.localizedDescription
            print(err)
        } else {
            print("succesfully authd")
            print(user)
        }
    })
}

(呃;记住任何人都可以访问这个节点。不要这样做!)

假设应用程序显示一个屏幕,用户可以使用登录按钮键入其用户名和密码。按登录按钮调用beginLogin函数,如下所示

public string Login(string username, string password)
    {
        if (!VerifyUserPassword(username, password))
            return "Wrong access";

        List<Claim> claims = GetUserClaims(username);

        RSACryptoServiceProvider publicAndPrivate = new RSACryptoServiceProvider();
        publicAndPrivate.FromXmlString(File.ReadAllText(HostingEnvironment.MapPath("~/AppKey.xml")));

        JwtSecurityToken jwtToken = new JwtSecurityToken
        (
            issuer: "http://example.com",
            audience: "http://receiver.com",
            claims: claims,
            signingCredentials: new SigningCredentials(new RsaSecurityKey(publicAndPrivate), SecurityAlgorithms.RsaSha256Signature),
            expires: DateTime.Now.AddDays(1)
        );

        JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler();
        string tokenString = tokenHandler.WriteToken(jwtToken);

        return tokenString;
    }