我在这里相对经常地问到这个问题,但是我仍然不知道如何管理唯一属性的规则。我有以下文档数据模型:
users/{usereId}/Object
users/usernames/Object
第一个对象包含有关用户的基本信息,例如:
{
email: "example@hotmail.edu"
photoURL: null
providerId: null
role: "admin"
username:"hello_world"
}
同时,用户名对象仅包含username
作为属性键,而uid
作为值,例如:
{
hello_world:"F3YAm8ynF1fXaurezxaQTg8RzMB3"
}
我以此方式进行设置,因为我希望每个用户都具有唯一的用户名。并且遍历第二个对象要比遍历第一个对象少。
但是回到我的问题。我需要hello_world
在写操作中是唯一的。但是到目前为止,我的规则仍然无效。我有:
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth.uid != null
}
match /users/{userID} {
allow create: if !exists(/databases/$(database)/documents/users/$(request.resource.data.username)) <== does not apply
}
}
}
第二个匹配项是应应用唯一属性规则的内容。有谁知道如何正确设置规则?
答案 0 :(得分:1)
您在usernames
集合中创建了一个名为users
的文档,以跟踪使用中的名称。但是您的规则正在尝试查找以当前用户名命名的文档,该文档在该结构中将永远不存在。
在当前结构中,您将需要以下内容:
allow create: if get(/databases/$(database)/documents/users/usernames).data[$(request.resource.data.username)] == request.auth.uid
因此,以上内容获取了保留所有用户名的文档,然后检查当前UID中是否包含当前用户名。
另一种方法是保留所有用户名的其他 集合,然后使其中的每个文档将单个用户名映射到UID。在这种情况下,您的/usernames
集合将是顶级的,因为它在所有用户之间共享。规则将更接近您当前拥有的:
allow create: if !exists(/databases/$(database)/documents/usernames/$(request.resource.data.username))
答案 1 :(得分:1)
由于您的用户名必须唯一,因此使用他们的名字作为文档密钥不是一种选择吗?