There is a pretty easy way on doing this.
Since you are using removeAllObservers
right after the the first callback I'm assuming that you might take a look on using observeSingleEventOfType
and you wont need to turn any observer later.
let username = self.usernameField.text
ref.child("Users").queryOrderedByChild("name").queryEqualToValue(username).observeSingleEventOfType(.Value, withBlock: { (snapshot) in
if snapshot.exists == true {
print("snapshot exists")
} else {
print("snapshot doesnt exist")
}
}) { (error) in
print(error.localizedDescription)
}
You should also write some database rules to guarantee the data consistency and performance in the server side. From the current structure you have this wont be straight-forward since you don't have the username
as the key for your Users
branch.
So I can see two possible solutions:
Username as the key
Saving the username
as the /Users
key you will just have a rule to enforce this key uniqueness.
{ "rules": {
"Users": {
".indexOn":
".write": "true",
"$username": {
".validate": "!root.child('Users').hasChild($username)"
}
}
}}
This would need some changes on your application code to see if this already exists
ref.child("Users").child(username).observeSingleEventOfType(.Value, withBlock: { (snapshot) in
if snapshot.exists == true {
print("snapshot exists")
} else {
print("snapshot doesnt exist")
}
}) { (error) in
print(error.localizedDescription)
}
Create a new branch to handle the username uniqueness
You want to keep the same structure you have today you will need to do some other changes. Just like the question that Frank linked you will need an extra branch only to store all the taken usernames. So whenever saving a new user you will need to first store the username in this other branch.
{ "rules": {
"Users": {
".indexOn": "name",
".write": "true",
"$id": {
".validate": "!root.child('already_taken_names').hasChild(newData.child('name').val())"
}
},
"already_taken_names": {
"$username": {
".validate": "!root.child('Users').hasChild($username)"
}
}
}}