【问题标题】:Firestore security rule: How to ensure uniqueness of values in document?Firestore 安全规则:如何确保文档中值的唯一性?
【发布时间】:2019-05-20 15:06:20
【问题描述】:

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

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安全规则是否有助于在允许创建文档之前确保字段值的唯一性?

【问题讨论】:

  • AFAIK 在将新文档发布到云存储集合之前,没有直接的 API 来检查集合是否已经具有相同值的文档。但是还有另一种方法,您应该查询集合的所有文档以检查是否已经有一个,这可以使用where() 完成,它接受三个参数:要过滤的字段、比较操作和价值。
  • 谢谢,但您的解决方案是在创建新文档之前进行客户端验证。 Firestore 安全规则是在创建新文档之前进行服务器端验证。这很重要。
  • 好吧,here 你可以阅读来自 Firebase 的 Frank van Puffelen 工程师关于这个主题的答案。我认为这不能仅通过安全规则来完成。

标签: firebase google-cloud-firestore


【解决方案1】:

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

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

换句话说,in this section:

资源变量引用请求的文档,并且 resource.data 是存储在 文件。

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

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

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

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

【讨论】:

    猜你喜欢
    • 2020-06-19
    • 1970-01-01
    • 2019-03-03
    • 1970-01-01
    • 2019-02-01
    • 1970-01-01
    • 2019-08-26
    • 2020-07-04
    • 1970-01-01
    相关资源
    最近更新 更多