Finding an UID by email in Firebase

做~自己de王妃 提交于 2021-02-16 14:07:22

问题


I first attempted to instantiate each user in the database like so:

emails : {
    email: "jerry@gmail.com" {
        uid: "x"
    }
}

I quickly found out that I can't store an email because it has an @ and .. I was originally going to do an user look up like so:

func userLookUpByEmail (email: String) -> String {
    var userID: String = "nil"

    ref.queryOrderedByChild("emails").queryEqualToValue(email).observeSingleEventOfType(.ChildAdded, withBlock: { snapshot in
            if snapshot.value != nil {
                print(snapshot.value)
                userID = snapshot.value as! String
            }
            else {
                print ("user not found")
                userID = "nil"
            }
    })
    return userID
}

However, I'm realizing that won't work. What is an effective way to receive an UID from providing an email?


回答1:


Answering your question, since you can't have the email as the child key you can do the other way, setting the uid as the key and the email as the child.

emails : {
    uid: {
        email: "jerry@gmail.com"
    }
}

And then your code will change a little bit.

func userLookUpByEmail (email: String, completionHandler: (result: String) -> Void) {
    var userID: String = "nil"
    ref.child("emails").queryOrderedByChild("email").queryEqualToValue(email).observeSingleEventOfType(.ChildAdded, withBlock: { snapshot in
                if snapshot.value != nil {
                    print(snapshot.key)
                    userID = snapshot.key as! String
                }
                else {
                    print ("user not found")
                    userID = "nil"
                }
                completionHandler(userID)
        })
 }

Calling userLookUpByEmail:

userLookUpByEmail(email) {
    (result: String) in
    print("\(result)")
}

On the other hand I'm wondering why do you have an emails branch in your database since you could have an users branch (if you don't have yet) and store any user data there, including the email. This would make your data structure much more clean and reliable. Again, I'm wondering here since I don't exactly know your needs.

users : {
    uid: {
        email: "jerry@gmail.com",
        name: "Jerry Maguire",
        ...
    }
}



回答2:


First of all, you are correct that you cannot store certain characters in the database. According to the Firebase docs, (https://firebase.google.com/docs/database/ios/structure-data)

If you create your own keys, they must be UTF-8 encoded, can be a maximum of 768 bytes, and cannot contain ., $, #, [, ], /, or ASCII control characters 0-31 or 127.

As you can see, however, the "@" symbol is not one of them. As for the dot, you can have a function that replaces the dot with another character. For example, "•". Here is an example:

func createNewEmail(oldEmail: String) -> String{
    return oldEmail.componentsSeparatedByString(".").joinWithSeparator("•")
}

What that does is it splits the email into an array of "email@example" and "com". Then, it re-joins them with the new character, creating "email@example•com"

If you ever needed the old email, you could just do the same thing in reverse.

func getOldEmail(newEmail: String) -> String{
    return newEmail.componentsSeparatedByString("•").joinWithSeparator(".")
}

You could then format your tree like this

emails:
    email@example•com: UID123456789

Finally, for your original question, the function could be written like this

func userLookUpByEmail (email: String) -> String {
    let newEmail = createNewEmail(email)
    var userID: String = "nil"

    ref.child("emails").child(newEmail).observeSingleEventOfType(.ChildAdded, withBlock: { snapshot in
            if snapshot.value != nil {
                print(snapshot.value)
                userID = snapshot.value as! String
            }
            else {
                print ("user not found")
                userID = "nil"
            }
    })
    return userID
}

However, it is possible that you will get "nil" every time. This is because observeSingleEventOfType is a closure. This means that it runs in the background of your app. Because of this, userID might be returned before it gets changed inside the closure. Instead of returning userID, you might want to run any code based on userID inside of the closure. For example, instead of doing this:

func userLookUpByEmail (email: String) -> String {
    let newEmail = createNewEmail(email)
    var userID: String = "nil"

    ref.child("emails").child(newEmail).observeSingleEventOfType(.ChildAdded, withBlock: { snapshot in
            if snapshot.value != nil {
                print(snapshot.value)
                userID = snapshot.value as! String
            }
            else {
                print ("user not found")
                userID = "nil"
            }
    })
    return userID
}

doSomethingWith(lookUserUpByEmail(email@example.com))

You could do this:

func userLookUpByEmail (email: String){
    let newEmail = createNewEmail(email)
    var userID: String = "nil"

    ref.child("emails").child(newEmail).observeSingleEventOfType(.ChildAdded, withBlock: { snapshot in
            if snapshot.value != nil {
                print(snapshot.value)
                userID = snapshot.value as! String
                doSomethingWith(userID)
            }
            else {
                print ("user not found")
                userID = "nil"
                doSomethingWith(userID)
            }
    })
}


来源:https://stackoverflow.com/questions/38040648/finding-an-uid-by-email-in-firebase

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!