问题
I try to prevent the creation of already existing usernames.
This is my code where I upload usernames to the database:
ref?.child("users").child(FIRAuth.auth()!.currentUser!.uid).child("username").setValue(self.createUserName.text)
And this is the code where I try to get if the username already exists or not
ref?.child("users")
.queryOrdered(byChild: "username")
.queryEqual(toValue: self.createUserName.text?.uppercased())
.observeSingleEvent(of: .value, with: { (snapshot) in
if !snapshot.exists() {
print("😍")
}
}) { error in
print("👾")
}
The database looks like this
Database_App {
users {
-3bSRmS4PHXUwsr7XbMBwgPozNfK2 {
username: "sebas.varela"
}
}
}
And appear this line in the console:
Consider adding ".indexOn": "username" at /users to your security rules for better performance
The problem is that I always get 😍. What is the problem with this?
回答1:
You can only query for values that are at a directly under the reference you query at. For your case that would be with a data model like:
Database_App {
users {
-3bSRmS4PHXUwsr7XbMBwgPozNfK2: "sebas.varela"
}
}
This will work in your code, but is hard to get secure and performant. The more common approach is to work with a extra node where you map user names to uids:
Database_App {
userNames {
"sebas,varela": "-3bSRmS4PHXUwsr7XbMBwgPozNfK2"
}
}
In this case the node essentially allows a user to claim their name. The advantage of this system is that the keys are automatically guaranteed to be unique on the server, no client-side code needed for that part.
You will want to:
- add security rules that ensure a user can only claim a username that hasn't been claimed yet
- also in these security rules allow a user to release their claim on a username
- add client-side code to handle conflicts in a nicer way than the default "permission denied" error you'll get from the server
来源:https://stackoverflow.com/questions/41110628/prevent-duplicate-users-with-firebase-database-swift-3