Reputation: 255
I have a little user login form, where the new user has to add his username, password and a nickname (as basic firebase auth only accepts e-mail as the username, right?).
This is a users structure I created on Firebase to receive the nickname
The key is based on the username and it has 2 children: the nickname and username.
Before I try to create the user using the auth methods from Firebase, I query to check if the nickname already exists. If yes, it doesn't create the user and throws an alert. If nickname doesn't exists, it creates the user and then adds the nickname to the users structure from the image above.
Some time thinking and changing the code here and there (code was jumping the 'observeSingleEventOfType' and executing the createUser, before check for if the nickname already existed), I thought a good idea was to get the createUser code and add it directly inside the observeSingleEventOfType on the nickname query, as an 'else' for 'if snapshot.exists()'...
It appears to be working, but I don't know if it is the 'correct' way to perform it...
Is there another way (a better way) to do it?
The method is below. Thanks!
func createUser(username: String, password: String, nickname: String){
var userCreated = false
var errorCode = 0
users.queryOrderedByChild("Nickname").queryEqualToValue(nickname).observeSingleEventOfType(.Value, withBlock: { (snapshot) in
if snapshot.exists() {
errorCode = 3
self.delegate?.didReceiveResponseFromFirebaseCreateUser!(userCreated, errorCode: errorCode)
}
else{
self.ref.createUser(username, password: password, withCompletionBlock: { (error) in
if error != nil {
print (error.description)
if error.description.rangeOfString("EMAIL_TAKEN") != nil {
errorCode = 1
}
else if error.description.rangeOfString("INVALID_EMAIL") != nil {
errorCode = 2
}
}
else{
userCreated = true
let newUser = User(username: username, nickname: nickname)
let newUserRef = self.users.childByAppendingPath(username.stringByReplacingOccurrencesOfString(".", withString: "-"))
newUserRef.setValue(newUser.toAnyObject())
}
self.delegate?.didReceiveResponseFromFirebaseCreateUser!(userCreated, errorCode: errorCode)
})
}
})
}
Upvotes: 0
Views: 1675
Reputation: 255
Just a heads up on the synchronicity issue I had with the Firebase Event Observer:
Yesterday, I thought it was working, I had issues when calling a segue to open another viewController (it was calling the new view while the Observer was still running with no results and the application crashed because the delegate method was using wasn't declared on the other view)...
As as solution, I got rid of all delegates and recoded the methods using completion handlers... Now its going really fine!
Oh, and @pkacprzak: I made the changes and started using this 'bridge structure' to store the relation between nickname and uid. Man, now its kicking! Thank u very much for it!
Upvotes: 0
Reputation: 5629
I have faced the same problem when I was building my last Firebase app. The method I used to solve it was to create an additional mapping from username to user ids. So my structure looks something like that (uid is user id from Firebase auth):
users: {
accounts: {
uid1: {
username: frank,
...
},
uid2: {
username: monique,
...
}
...
},
username_to_uid: {
frank: uid1,
monique: uid2,
...
}
}
This allows two major things:
Upvotes: 3