且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Firebase在Swift中的用户名唯一性

更新时间:2023-11-28 12:29:34

您的问题在于您的安全规则。用户进行身份验证之前,您正在执行查询。此查询将失败,因为您的规则声明用户必须通过身份验证才能查询数据库(auth!= null)。



您需要做的是创建另一个孩子叫用户名。让任何人都可以阅读,而不需要验证检查用户名是否被采用,如果没有,请为新用户声明。然后,进行身份验证调用,并在用户子中创建用户。


I am trying to check username uniqueness while registering user. I know there are tons of questions about it and I went through all of them however my problem is that it doesn't do anything, it doesn't print that the username exists and it even doesn't register with the username.

What I am doing wrong? I can't seem to find answer, the only thing that could be wrong is the if nesting.

This is the struct:

AppName:
    users
     1v2mRJTvrBQ7dMQohUU3rnn7ypI3: //UID
     username: John

And that is the code:

func registerUser(){
        guard let username = usernameField.text, let email = emailField.text, let password = passwordField.text else{
            print("Successfully registered")
            return
        }
        if connectedToNetwork() == true{
            if passwordField.text == confirmPasswordField.text{
                let usersRef = FIRDatabase.database().reference().child("users")
                usersRef.queryOrdered(byChild: "username").queryEqual(toValue: "\(username)")
                .observeSingleEvent(of: FIRDataEventType.value, with: { (snapshot) in
                    if snapshot.value is NSNull{

                AuthProvider.Instance.register(withEmail: email, password: password, username: username, loginHandler: { (errMessage) in
                    if errMessage != nil{

                    }else{
                        let user = FIRAuth.auth()?.currentUser
                        guard let uid = user?.uid else{
                            return
                        }
                        user?.sendEmailVerification() { error in
                            if let error = error {
                                print(error.localizedDescription)
                            } else {
                                print("Email has been sent to you!")
                            }
                        }
                        //User logged in and redirect

                    }
                })
                    }else{
                    print("Username already exists")// It doesn't execute this
                    }
                })
            }else{
                Util.errorAlert(message: "Passwords do not match!")
            }
        }else{
            Util.errorAlert(message: "The internet connection appears to be offline.")
        }
    }

I even tried different security rules but those shouldn't make any difference but those that I used:

{ 
"rules": { 
".read": "auth != null", 
".write": "auth != null", 
"Snuses": { 
".indexOn": "Brand",
    "$username": {
        ".validate": "!root.child(users').hasChild($username)"
    }
} 
} 
}

What is the thing I am doing wrong?

Your problem is in your security rules. You're doing a query before the user has been authenticated. This query will fail because your rules state that the user has to be authenticated in order to query the database (auth != null).

What you need to do is create another child called "usernames". Make this readable by anyone without authentication. Check if the username is taken and if not, claim it for the new user. Then, do your auth call and create your user in the "users" child.