我试图防止创建已经存在的用户名。
这是我的代码,我将用户名上传到数据库:
ref?.child("users").child(FIRAuth.auth()!.currentUser!.uid).child("username").setValue(self.createUserName.text)
这是我尝试获取用户名是否已经存在的代码
ref?.child("users")
.queryOrdered(byChild: "username")
.queryEqual(toValue: self.createUserName.text?.uppercased())
.observeSingleEvent(of: .value, with: { (snapshot) in
if !snapshot.exists() {
print("😍")
}
}) { error in
print("👾")
}
数据库看起来像这样
Database_App {
users {
-3bSRmS4PHXUwsr7XbMBwgPozNfK2 {
username: "sebas.varela"
}
}
}
并在控制台中显示此行:
Consider adding ".indexOn": "username" at /users to your security rules for better performance
问题是我总是得到😍
。这个问题是什么?
您只能查询直接在您查询的参考下的值。对于您的情况,将与以下数据模型相关。
Database_App {
users {
-3bSRmS4PHXUwsr7XbMBwgPozNfK2: "sebas.varela"
}
}
这将在您的代码中起作用,但是很难获得安全和性能。更常见的方法是使用一个额外的节点,在其中将用户名映射到UID:
Database_App {
userNames {
"sebas,varela": "-3bSRmS4PHXUwsr7XbMBwgPozNfK2"
}
}
在这种情况下,节点本质上允许用户声明其名称。该系统的优势在于,键可以自动保证在服务器上是唯一的,该部分不需要客户端代码。
您将要:
- 添加安全规则,以确保用户只能要求尚未要求的用户名
- 在这些安全规则中也允许用户在用户名上发布其主张
- 添加客户端代码以比默认的"权限拒绝"错误以更好的方式处理冲突