【问题标题】:Allow update on single field in firestore允许更新 Firestore 中的单个字段
【发布时间】:2018-09-15 05:01:06
【问题描述】:

我想授予用户更新文档的权限。但仅当用户更新此文档的一个特定字段时。此用户不应更改所有其他字段。

这在 Firestore 中可行吗?

我尝试过这样的事情:

function isUpdateToOpenField(attr) {
    return attr == get(/databases/$(database)/documents/stores/$(store)).data.open;
}

allow update: if isUpdateToOpenField(request.resource.data);

但我不知道如何比较更新是否对应正确的字段。

【问题讨论】:

    标签: google-cloud-firestore firebase-security


    【解决方案1】:

    引入了规则语言中的地图差异来解决这个问题:

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

    【讨论】:

    • 您将attr 发送给函数,但从不使用它
    • 现在你的函数没有接收任何参数,但你发送它request.resource.data :)
    【解决方案2】:

    你可以使用:

    allow update: if request.resource.data.diff(resource.data).affectedKeys().hasOnly(["fieldToBeUpdated"]);
    

    allow update: if request.resource.data.diff(resource.data).affectedKeys() == ["fieldToBeUpdated"].toSet;
    

    您可以将 affectedKeys() 替换为 addedKeys()removedKeys()changedKeys() ,具体取决于您的用例。

    affectedKeys()顾名思义就相当于三个一起使用。

    有关更多详细信息,请阅读此处的文档https://firebase.google.com/docs/reference/rules/rules.MapDiff

    【讨论】:

      【解决方案3】:

      “Scott Crossen”的答案几乎没有变化,更通用

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

      【讨论】:

        【解决方案4】:

        更新:您现在可以使用 Map.diff() 代替 writeFields

        查看writeFields 变量以了解安全规则:

        allow update: if ((request.writeFields.size() == 1) && ('open' in request.writeFields));
        

        【讨论】:

        • writeFields 与嵌套字段的外观如何,例如>> 更新(“foo.bar”,baz)?谢谢。
        • @lenhuy2106:这个&& ('foo.bar' in request.writeFields) 按预期工作。
        【解决方案5】:

        由于request.resource.data 将在写入后显示未来对象 - 唯一的方法是使用以下方法检查每个字段

           function notUpdating(field) {
             return !(field in request.resource.data)
              || resource.data[field] == request.resource.data[field]
           }
        
           allow update: if notUpdating('title') && notUpdating('description')
        

        确保您确认用户没有更新除您希望他有权访问的字段之外的所有字段

        【讨论】:

          【解决方案6】:

          由于 writeFields 已弃用且不应使用,因此您必须检查 request.resource.data。但是,它始终包含书面文档的所有字段(它是最终状态)。这意味着您必须将书面文档的所有字段与resource.data 中原始文档的字段进行比较,以确保只有更改的字段是您允许更改的字段。

          目前,这需要对可能写入的每个字段进行显式检查,实现起来并不有趣。 Firebase 团队正在研究通过允许您区分“之前”和“之后”文档的数据映射来使此类规则更易于表达的方法。

          【讨论】:

          • 这是一个讨论此策略的helpful article。对于更复杂的断言非常痛苦。我希望这个问题能尽快得到解决。
          • 嗨,这个话题有更新吗?谢谢
          猜你喜欢
          • 2020-08-17
          • 1970-01-01
          • 2019-09-10
          • 1970-01-01
          • 2019-02-04
          • 1970-01-01
          • 2020-05-31
          • 2020-09-18
          • 2019-03-12
          相关资源
          最近更新 更多