Firestore中唯一属性的Firebase规则

时间:2018-07-16 14:04:54

标签: firebase google-cloud-firestore

我在这里相对经常地问到这个问题,但是我仍然不知道如何管理唯一属性的规则。我有以下文档数据模型:

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
    }

  }
}

第二个匹配项是应应用唯一属性规则的内容。有谁知道如何正确设置规则?

在控制台中,对象模型如下所示

enter image description here

enter image description here

2 个答案:

答案 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)

由于您的用户名必须唯一,因此使用他们的名字作为文档密钥不是一种选择吗?