在Firebase中查询用户以检查注册过程中是否存在用户名

时间:2016-06-30 23:23:31

标签: ios swift firebase

问题

如何在用户注册过程中检查用户名是否已存在?

我不知道如何查询Firebase以确定是否存在特定值。

背景

Firebase结构:

Users
    0BBfrF1vVBXXxNxeVMes9MFkYNJ3
    name: "SAM"

    0oU9sf7CZxaDBx03t87lqTrv9UM2
    name: "JACK"

    IsXEqXov0obuwl1WOrHhCbfdfEo1
    name: "JEREMY"

在下面的代码中:

  • 我尝试检查usernameField
  • 中是否存在值users\userID\name
  • child(userID)无法检索任何内容

_

let username = self.usernameField.text

        let userRef = ref.child("Users").child(userID).child("name")

        userRef.observeEventType(.Value, withBlock: { snapshot in

            if snapshot.value!.isEqual(username) {

                print("snapshot exists")

            } else {

                print("snapshot doesnt exist")

            }


            userRef.removeAllObservers()

            }, withCancelBlock: { error in

                print(error)

        })

1 个答案:

答案 0 :(得分:3)

这样做有一个非常简单的方法。

由于您在第一次回调后正在使用removeAllObservers我假设您可以使用observeSingleEventOfType来查看,并且您不需要稍后转动任何观察者。

let username = self.usernameField.text
ref.child("Users").queryOrderedByChild("name").queryEqualToValue(username).observeSingleEventOfType(.Value, withBlock: { (snapshot) in 
    if snapshot.exists == true {
        print("snapshot exists")
    } else {
        print("snapshot doesnt exist")
    }
}) { (error) in
   print(error.localizedDescription)
} 

您还应该编写一些数据库规则来保证服务器端的数据一致性和性能。从目前的结构来看,由于没有username作为Users分支的密钥,因此不会直截了当。

所以我可以看到两种可能的解决方案:

用户名为密钥

username保存为/Users密钥,您将只有一条规则来强制执行此密钥唯一性。

{ "rules": { 
  "Users": {
    ".indexOn":
    ".write": "true",
    "$username": {
        ".validate": "!root.child('Users').hasChild($username)"
    }
  }
}}

这需要对您的应用程序代码进行一些更改,以确定它是否已存在

ref.child("Users").child(username).observeSingleEventOfType(.Value, withBlock: { (snapshot) in 
        if snapshot.exists == true {
            print("snapshot exists")
        } else {
            print("snapshot doesnt exist")
        }
    }) { (error) in
       print(error.localizedDescription)
    } 

创建一个新分支来处理用户名唯一性

您希望保持今天的结构,您需要做一些其他更改。就像Frank链接的问题一样,你需要一个额外的分支来存储所有被占用的用户名。因此,无论何时保存新用户,您都需要先将该用户名存储在另一个分支中。

{ "rules": { 
  "Users": {
    ".indexOn": "name",
    ".write": "true",
    "$id": {
        ".validate": "!root.child('already_taken_names').hasChild(newData.child('name').val())"
    }
  },
  "already_taken_names": {
    "$username": {
        ".validate": "!root.child('Users').hasChild($username)"
    }
  }
}}