无法检查唯一的用户名(Firebase)

时间:2016-09-09 18:37:01

标签: ios swift firebase firebase-realtime-database

我正在尝试检查用户输入的用户名是否唯一,并且与当前数据库中的任何用户名不匹配。我在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。有关重组代码的任何建议吗?

1 个答案:

答案 0 :(得分:2)

那不行。从Firebase数据库加载数据需要时间和异步(就像几乎所有的现代Web编程一样)。这意味着在加载数据时您的主代码会继续。然后,当数据可用时,将调用您的回调/ 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)
   }

这通常被称为"反应式编程风格"或"事件驱动编程"。所以如果你看到这些条款:你现在已经掌握了它们。 : - )

相关问题