Tarvo Mäesepp Tarvo Mäesepp - 19 days ago 5
Swift Question

Firebase username uniqueness in Swift

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?

Answer

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.