【问题标题】:Firestore rules: Prevent overwrite of propertyFirestore 规则:防止覆盖属性
【发布时间】:2020-05-13 13:27:37
【问题描述】:

在 Firestor 规则中,如何允许将新文档创建到集合中,并将新值添加到文档中,但不允许覆盖文档中的值?

请参阅以下内容以获得更清晰的理解:

集合 -------------- 文档 -------------- 值

用户 -------- DonutCoder -------------- isAdmin,birthDate

现在,如果我想将电子邮件添加到文档 Donut Coder 下的值,我该如何执行此操作但要防止覆盖(例如,将 isAdmin 更改为 true,以便用户获得更多权限)

我已经尝试过:allow read, create - 但这允许创建新文档但不能更改文档中的属性。

【问题讨论】:

  • 我自己还没有尝试过,但是你应该可以在安全规则中使用这些新的地图操作:firebase.google.com/support/release-notes/…
  • 抱歉没用
  • 请编辑问题以显示您希望在这种情况下允许的特定客户端代码。您可能可以使用新的MapDiff API 来检测和允许这种情况。如果您编写了一条规则但它不起作用,请编辑问题以同时显示您尝试过的内容。

标签: firebase google-cloud-firestore firebase-security


【解决方案1】:

1) 不要添加任何覆盖相同路径的代码。

2) 为防止他人对其进行逆向工程并对其进行更新,请添加以下内容:

allow update: if false

再次,任何人仍然可以尝试再次创建相同的文档,因此您需要为其添加更多安全规则。请检查official documentation

我有类似问题的答案,但它们指的是实时数据库。虽然你可以检查它here

allow update: if false 只是阻止更新现有值。

【讨论】:

  • 您好,谢谢您的回复。不幸的是,这也阻止了我写作。
  • 我需要能够添加新属性但不能更改或删除旧属性
  • @DonutCoder 你想在同一个文档中创建新属性吗?
  • @DonutCoder 你应该保留允许写入:如果为真
  • 嗨:这就是我所拥有的:允许读取允许写入:如果为真允许更新:如果为假,它允许我读写和更新
【解决方案2】:

防止 isAdmin 或birthDate 被更新:

allow update: if request.resource.data.isAdmin = resource.data.isAdmin
  && request.resource.data.birthDate = resource.data.birthDate;

您可以根据需要开始在此基础上进行构建。例如,如果您希望只允许登录用户并且一次只修改一个字段:

allow update: if request.auth.uid != null
  && request.resource.data.diff(resource.data).affectedKeys().size() == 1 
  && request.resource.data.isAdmin = resource.data.isAdmin
  && request.resource.data.birthDate = resource.data.birthDate;

【讨论】:

    【解决方案3】:

    这个官方文档页面似乎显示了如何做到这一点:https://firebase.google.com/docs/firestore/security/rules-fields#preventing_some_fields_from_being_changed

    allow update: if (!request.resource.data.diff(resource.data).affectedKeys().hasAny(['average_score', 'rating_count']));
    

    【讨论】: