我正在尝试检查用户输入的用户名是否唯一,并且与数据库中当前的任何用户名都不匹配。我在Stackoverflow上发现了很多类似的问题,但似乎都不适合我。以下是我当前的数据结构:
users
-C3M483C28M34C29834C (uid)
• username: "myUsername"
我现在使用的东西大致如下:
let ref = FIRDatabase.database().reference()
var usernameTaken = false
ref.child("users").queryOrderedByChild("username").queryEqualToValue(username.text?.uppercaseString).observeSingleEventOfType(.Value, withBlock: { snapshot in
if snapshot.exists(){
usernameTaken = true
}else{
usernameTaken = false
}
}) { error in
print(error.localizedDescription)
}
if usernameTaken == false{
//do stuff with unique username
}
这很好,快照被接收。但是,当我尝试检查数据是否存在时,总是显示为false。有什么关于重新组织法典的建议吗?
最佳答案
那是行不通的。从Firebase数据库加载数据需要时间,而且是异步的(就像几乎所有的现代web编程一样)。这意味着在加载数据时主代码将继续。然后当数据可用时,将调用callback/withBlock。通过在代码中添加一些日志记录,您可以很容易地看到这一点:
print("Before attaching observer")
ref.child("users")
.queryOrderedByChild("username")
.queryEqualToValue(username.text?.uppercaseString)
.observeSingleEventOfType(.Value, withBlock: { snapshot in
print("In observer block")
})
print("After attaching observer")
其输出为:
附加观察者之前
附加观察者后
在观察块中
这可能不是你所期望的顺序。如前所述,代码在查询部分之后继续,您的块稍后被调用,可能要晚得多。
解决办法是重新定义你的思维方式。现在你的代码是“先做abc,然后做xyz”。如果你把它改成“当abc发生时,用它来做xyz”,你会突然少出一些问题。
ref.child("users")
.queryOrderedByChild("username")
.queryEqualToValue(username.text?.uppercaseString)
.observeSingleEventOfType(.Value, withBlock: { snapshot in
if !snapshot.exists(){
//do stuff with unique username
}
}) { error in
print(error.localizedDescription)
}
这通常被称为“反应式编程风格”或“事件驱动编程”。所以如果你看到这些术语:你现在已经掌握了它们。:-)
关于ios - 无法检查唯一的用户名(Firebase),我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39417826/