【问题标题】:Firebase (firestore) rules: ensure update only if another document is updated (FieldValue increase)?Firebase(firestore)规则:仅在更新另一个文档时确保更新(FieldValue 增加)?
【发布时间】:2019-09-20 09:36:15
【问题描述】:

我正在尝试在集合内创建一个stats 文档,并且我希望仅在同一集合内更新另一个文档时才允许更新它(简而言之,批量写入)。有什么方法可以确保在此请求期间更新另一个文档?

我什至考虑允许它客户端的原因是由于以下来源:Keep a Count of Documents in a Collection

有没有更好的方法来计算文档数量? (我不在乎这是否是对 REST API 的实际调用,而不是通过 SDK)。

我正在验证 stats 是否根据在该其他文档上收到的请求数据(私有 => 公有、公有 => 私有、创建、删除...)正确更新,因为我知道确切的 stats 文档的路径显然

但我不知道如何确保 stats 只能在/如果另一个文档更新时更新(除了显而易见的,我在旁边传递了该文档的 ID)。 p>

我的规则的简短版本是:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if false;
    }
    match /stories/---STATS--- {
      allow read;
      allow create, update;
    }

    match /stories/{storyId} {
      allow read: if isPublic() || isAuthor();
      allow create: if
        isSignedIn() &&
        updatedStats() &&
        validateCreate();

      function updatedStats() {
        return getAfterStats().updatedAt == request.time;
      }
      function validateCreate() {
        return
          ( // Created public
            new().public &&
            isIncreaseN() &&
            isIncreaseNAll()
          ) ||
          ( // Created private
            !new().public &&
            isUntouchedN() &&
            isIncreaseNAll()
          );
      }
      // COUNTERS
      function isStats() {
        return exists(/databases/$(database)/documents/stories/---STATS---);
      }
      function getStats() {
        return get(/databases/$(database)/documents/stories/---STATS---).data;
      }
      function getAfterStats() {
        return getAfter(/databases/$(database)/documents/stories/---STATS---).data;
      }
      // n
      function isIncreaseN() {
        return  (!isStats() && getAfterStats().n == 1) ||
                (!getStats().keys().hasAll(['n']) && getAfterStats().n == 1) ||
                (getStats().n +1 == getAfterStats().n);
      }
      function isUntouchedN() {
        return  (!isStats() && !getAfterStats().keys().hasAll(['n'])) ||
                (!getStats().keys().hasAll(['n']) && !getAfterStats().keys().hasAll(['n'])) ||
                (getStats().n == getAfterStats().n);
      }
      // nAll
      function isIncreaseNAll() {
        return  (!isStats() && getAfterStats().nAll == 1) ||
                (!getStats().hasAll(['nAll']) && getAfterStats().nAll == 1) ||
                (getStats().nAll +1 == getAfterStats().nAll);
      }
  }
}

// GETTERS
function new() {
  return request.resource.data;
}
function cur() {
  return resource.data;
}
function auth() {
  return request.auth;
}

// MISC
function isSingedIn() {
  return auth() != null;
}

我对@9​​87654327@ 文件有更多的验证规则,例如只允许某些字段存在,只允许递增/递减 1 等,但即使没有触及任何实际的 story,也没有什么能真正阻止增加这个值.

【问题讨论】:

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


    【解决方案1】:

    在 Firebase 安全规则中,无法知道集合中的某个任意文档是否与另一个文档一起更改。您必须知道批量写入中所有文档的完整路径,才能查看它们是否一致更改。

    【讨论】:

    • 那么我想我也必须传递 ID。我会再等几天,以防出现其他答案,然后再接受它作为最终答案。感谢您的快速响应。
    猜你喜欢
    • 1970-01-01
    • 2020-06-19
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    • 1970-01-01
    • 2019-12-18
    • 2021-04-24
    • 2021-05-15
    相关资源
    最近更新 更多