在 Firebase 中通过电子邮件查找 UID
Posted
技术标签:
【中文标题】在 Firebase 中通过电子邮件查找 UID【英文标题】:Finding an UID by email in Firebase 【发布时间】:2016-06-26 16:28:46 【问题描述】:我首先尝试像这样实例化数据库中的每个用户:
emails :
email: "jerry@gmail.com"
uid: "x"
我很快发现我无法存储电子邮件,因为它有 @
和 .
。我原本打算像这样进行用户查找:
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
但是,我意识到这行不通。通过提供电子邮件接收 UID 的有效方法是什么?
【问题讨论】:
您的数据结构不是有效的 JSON。请使用有效的 JSON 更新您的问题。 这样的东西似乎是最简单的数据结构来做你正在寻找的东西:***.com/questions/37897656/… 【参考方案1】:回答您的问题,因为您不能将电子邮件作为子键,您可以以另一种方式,将 uid 设置为键,将电子邮件设置为子键。
emails :
uid:
email: "jerry@gmail.com"
然后你的代码会发生一点变化。
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)
)
致电userLookUpByEmail
:
userLookUpByEmail(email)
(result: String) in
print("\(result)")
另一方面,我想知道为什么你的数据库中有一个 emails
分支,因为你可以有一个 users
分支(如果你还没有的话)并在那里存储任何用户数据,包括电子邮件。这将使您的数据结构更加干净和可靠。再说一次,我在这里想知道,因为我不完全了解您的需求。
users :
uid:
email: "jerry@gmail.com",
name: "Jerry Maguire",
...
【讨论】:
我收到错误Using an unspecified index. Consider adding ".indexOn": "email" at /emails to your security rules for better performance
。我的规则应该看起来像 "rules": ".read": "auth != null", ".write": "auth != null" "/emails" ".indexOn" : "email"
吗?
@user5812721 这不是错误。您的代码应该在没有它的情况下工作,因为它只是为了内部 firebase 性能。您正在寻找的规则是: "rules": ".read": "auth != null", ".write": "auth != null", "emails": ".indexOn" : "email"
在我添加规则之前会找到快照键,但现在它总是为零。同样在我的)
之后,我写了print(userid)
但它也出现了零,这就是为什么我认为这是一个错误。在我添加规则之前,我在第一个 if 语句中打印了快照键,它总是正确的。
@user5812721 您通过了身份验证吗?此外,如果您尝试在 )
之后打印用户 ID,它将失败,因为您是从异步回调函数中调用它。如果你想在我的代码中找到的 return 语句之前打印它。
@user5812721 我的错,你根本无法返回。在这种情况下,您应该使用completionHandler。我已经用正确的信息编辑了这个问题。无论如何,很高兴你做到了。 :)【参考方案2】:
首先,您不能在数据库中存储某些字符是正确的。根据 Firebase 文档,(https://firebase.google.com/docs/database/ios/structure-data)
如果您创建自己的密钥,它们必须是 UTF-8 编码的,最多可以是 768 个字节,并且不能包含 .、$、#、[、]、/ 或 ASCII 控制字符 0-31 或 127 .
但是,正如您所见,“@”符号不是其中之一。至于点,您可以使用一个函数将点替换为另一个字符。例如, ”•”。这是一个例子:
func createNewEmail(oldEmail: String) -> String
return oldEmail.componentsSeparatedByString(".").joinWithSeparator("•")
它的作用是将电子邮件拆分为“email@example”和“com”的数组。然后,它用新字符重新加入它们,创建“email@example•com”
如果您曾经需要旧电子邮件,您可以反过来做同样的事情。
func getOldEmail(newEmail: String) -> String
return newEmail.componentsSeparatedByString("•").joinWithSeparator(".")
然后你可以像这样格式化你的树
emails:
email@example•com: UID123456789
最后,对于你原来的问题,函数可以这样写
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
但是,您可能每次都会得到“nil”。这是因为observeSingleEventOfType 是一个闭包。这意味着它在您的应用程序的后台运行。因此,用户 ID 可能会在闭包内更改之前返回。您可能希望在闭包内运行基于 userID 的任何代码,而不是返回 userID。例如,不要这样做:
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))
你可以这样做:
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)
)
【讨论】:
我将它保存到一个名为temp_uid
的类的变量中,然后在我调用userLookUpByEmail
之后将该变量保存到user2uid
,但temp_uid
仍然没有及时收到正确的值.
@user5812721 你基本上不能把任何东西放在闭包之外。在大多数情况下,您放在括号外的任何内容都无法正常工作。试图打败时钟是行不通的。你需要把你想用snapshot
做的everything放在闭包中。如果您想对这些值做一些事情,请创建一个函数,然后将其放入其中。比如我放doSomethingWith(userID)
的地方,你想放什么就放什么。
澄清一下......您可以将数据存储在闭包/块之外,但在快照在块内有效之前,您不应对该数据采取行动。因此,例如,您可以在块之外拥有一个类级别数组 self.myArray(一个 tableview 数据源)。您将从块内的快照中填充该数组,并告诉您的 tableview 从块内重新加载自己,在填充数组后,再次在块内。以上是关于在 Firebase 中通过电子邮件查找 UID的主要内容,如果未能解决你的问题,请参考以下文章
如何从 Flutter 应用程序中删除 firebase 用户? [复制]
如何根据数据库用户 id(不是 uid)设置 firebase 规则
在 Firestore 中通过 docId 批量设置文档字段时遇到问题