【问题标题】:Number of update fields in firestore security rulesFirestore 安全规则中的更新字段数
【发布时间】:2019-06-17 00:18:10
【问题描述】:

我正在从客户端进行批量操作以仅更新一个字段,但是在进行批量操作并在安全规则中进行测试时,观察到多个字段正在更新。我使用request.resource.data.size() >1 和request.resource.data.keys().size()>1 进行了检查,返回true(文档正在更新),但这不是我想要检查的安全规则,即只有一个字段正在使用request.resource.data.keys().hasOnly(['someFieldToUpdate']) 之类的检查进行更新,但这不是现在工作,以前我记得有 writeFields 来检查它,但它现在不在文档中,而且 this 答案也提到了它。那么如何检查现在在批处理操作中实际上正在更新的字段呢?

【问题讨论】:

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


    【解决方案1】:

    您可以在数据映射上使用新的diff() 方法。它会告诉您更改了哪些键。这是一个示例:

    function isUpdateToOpenField(attr) {
        return request.resource.data.diff(resource.data).changedKeys().hasOnly(['open']);
    }
    
    allow update: if isUpdateToOpenField(request.resource.data);
    

    改编自this answer。

    【讨论】:

      【解决方案2】:

      request.resource.data 字段包含资源,因为它将在写入操作成功后存在。 writeFields 属性已被删除,因为它无法始终可靠地填充。

      现在我能想到的唯一选择是检查每个单独的字段是否已更改,然后仅在有一个更改时才允许它。但老实说,这听起来像是一个奇怪的用例。一个更常见的用例是限制用户可以更新的什么特定字段,而不是一次可以更新多少。

      【讨论】:

      • 我确实希望用户更新一个“特定”字段,而不是我使用 request.resource.data.keys().hasOnly(['someFieldToUpdate']) 检查的任何其他字段,我给了一个关于字段数量的示例,只是为了说明 request.resource.data 中的键比客户端实际更新的键多。现在我知道 request.resource.data 告诉写操作后文档的状态。所以总结一下,检查是否只有一个特定字段被更新的唯一方法是检查所有字段是否已更改并据此做出决定。
      • 确实是这样。您必须检查所有这些字段是否为request.resource.data.field == resource.data.field。
      • 这太痛苦了,因为该文档有超过 10 个字段并且还有子对象,因此无法检查子对象的相等性,因为子对象中的键不同取决于其他一些逻辑。我能看到的唯一方法是使用云功能并在更改不满足条件时恢复到以前的状态。我想念writeFields:P
      • @FrankvanPuffelen 如果您有一个复杂的对象,这尤其困难。就我而言,我有一个用户文档,我希望用户只更新名称。它里面有多个地图,这些地图通过云功能写入用户文档,我不希望这些地图被更新。在安全规则中,我无法检查映射是否相等,因为键不是固定的,值是对象。我解决这个问题的唯一方法是编写一个云函数,它只接受一个名称并更新用户文档中的名称。如果我可以在这里使用安全规则,那就太好了。
      猜你喜欢
      • 2020-06-19
      • 2018-03-27
      • 1970-01-01
      • 1970-01-01
      • 2020-02-13
      • 2019-01-09
      • 1970-01-01
      • 2019-01-15
      相关资源
      最近更新 更多