Firestore安全规则:如何确保文档中值的唯一性?

时间:2018-12-20 05:21:20

标签: firebase google-cloud-firestore

下面的安全规则能否在配置文件集合中创建文档之前确保名字,姓氏,用户名和电子邮件的唯一性?

match /profiles/{document=**} {
   allow create: if request.auth.uid != null
   && (request.resource.data.firstName is string && resource.data.firstName != request.resource.data.firstName)
   && (request.resource.data.lastName is string && resource.data.firstName != request.resource.data.firstName)
  && (request.resource.data.username is string && resource.data.username != request.resource.data.username)
  && (request.resource.data.email is string && resource.data.email != request.resource.data.email)
}

例如,以下是Firestore集合配置文件中的数据

{
   "document1":{
      "firstName":"Jek",
      "lastName":"Choo",
      "email":"jeksomething@gmail.com",
      "username":"jek"
   },
   "document2":{
      "firstName":"Cara",
      "lastName":"Choo",
      "email":"babycara@gmail.com",
      "username":"cara"
   }
}

我要创建以下新文档,并且此创建访问权限应被拒绝

{
   "document3":{
      "firstName":"Jek",
      "lastName":"Choo",
      "email":"jeksomething@gmail.com",
      "username":"jek"
   }
}

我想创建下面的新文档,这应该被允许。

{
   "document4":{
      "firstName":"example",
      "lastName":"com",
      "email":"test@example.com",
      "username":"example"
   }
}

总而言之,上述Firestore安全规则能否帮助确保在允许创建文档之前字段值的唯一性?

1 个答案:

答案 0 :(得分:3)

了解resource对创建新文档的规则的作用很重要,这是您在此处显示的唯一规则。

resource是指“正在写入的(现有)文档”。这与request.resource相反,后者描述了如果写入成功将不存在,即将存在的文档。

换句话说,in this section

  

资源变量引用请求的文档,并且   resource.data是存储在数据库中的所有字段和值的映射   文档。

在创建的情况下,没有现有文档被写入。因此,您可以假定与resource的任何匹配都将失败。因此,这不能确保唯一性。

实际上,您不能确保创建任何给定文档字段的唯一性,因为在安全规则中无法查询该集合中所有文档是否存在该字段。

Firestore观察到的唯一唯一形式是集合中文档ID的唯一形式。安全规则不能将该文档的所有字段限制为唯一,并且Firestore中没有确保唯一性的索引。

如果您需要一个唯一的字段,则应在之后使用Cloud Function触发器检查文档创建,然后在不满足要求时删除该文档。