【问题标题】:List collections based on document IDs根据文档 ID 列出集合
【发布时间】:2020-09-01 05:50:21
【问题描述】:

我正在尝试列出其 ID 以数组形式给出的所有文档。

规则:

rules_version = '2';
service cloud.firestore {

  match /databases/{database}/documents {

    function isSignedIn() {
      return request.auth.uid != null;
    }

    function checkUserId(orgId) {
      return ('user_id' in resource.data.keys() && request.auth.uid==resource.data.user_id)
        || orgId in get(/databases/$(database)/documents/user/$(request.auth.uid)).data.organisationIds;
    }

    function checkAdminToken() {
      return 'lectusAdmin' in request.auth.token.keys() && request.auth.token.lectusAdmin
    }

    match /organisation/{document=**} {
      allow read, update, delete: if isSignedIn() && (checkUserId(document) || checkAdminToken()); // This is line 20
      allow create: if isSignedIn();
    }

  }

}

我的 Angular 10 代码是:

this.organisationCollection = this._angularFirestore.collection<Organisation>('organisation');
this.organisations = this.organisationCollection.valueChanges({idField: 'id'});

我尝试在集合中添加一个where - .where('id', 'in', org.organisationIds),其中id 是检查org.organisationIds 数组的文档ID(我认为是这样)。同样,我不确定我是否需要这个,因为规则应该能够解决这个问题。

我收到一个错误 - false for 'list' @ L20 那是 - allow read, update, delete: if isSignedIn() &amp;&amp; (checkUserId(document) || checkAdminToken());

当我尝试使用 orginisation/&lt;document ID&gt; 获取文档但我无法列出它们时,这可以正常工作。

任何帮助将不胜感激。

【问题讨论】:

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


    【解决方案1】:

    您遇到的问题是Firestore security rules are not filters.请仔细阅读该文档。规则将检查整个查询结果集中每个文档的内容 - 这不会按照 Firestore 要求的方式进行扩展。 Firestore 每个集合可扩展到数十亿或更多文档。阅读和检查每个文档是不可能的。

    您的查询声明它需要“组织”集合中的所有文档。由于规则无法确保使用您现在拥有的检查(必须检查每个文档的内容,甚至是其他文档)来确保每个文档都是可读的,因此它们只会使整个查询失败。

    让您的查询工作的唯一方法是它是否符合规则要求。例如,如果您的规则要求用户的 ID 必须等于文档中的字段“user_id”,那么您需要将用户的 UID 添加为查询中该字段的过滤器。但是您仍然无法根据资源文档中的字段get()规则中的其他文档(因为它仍然不会读取每个文档来检查它)。

    【讨论】:

    • 好的。我不希望它检查每个文档的内容,get(/databases/$(database)/documents/user/$(request.auth.uid)).data.organisationIds 返回一个数组。我只想检查所请求的 ID 在此是否可用。或者这是正在发生的事情,这是不可能的?
    • 您的规则会在您看到resource 时使用特定文档的内容。如果您将其用于可能返回多个文档的查询,它将失败。
    • 啊,明白了。对此有任何建议,因为如果我不检查,checkUserId() 在第一个条件下会失败,因为资源可能没有user_id,这可能是一个安全问题
    • 我的建议是通过添加过滤器使查询匹配规则。
    • 类似where('id', 'in', org.organisationIds)?但是该文档没有id 字段,我不知道在使用where 查询时如何在其集合中获取文档ID
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-13
    • 1970-01-01
    • 2019-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-18
    相关资源
    最近更新 更多