当前位置: 首页 > 知识库问答 >
问题:

Firebase FiRecovery子集合安全查询

戚晨
2023-03-14

我的云Firestore数据库中有以下规则:

service cloud.firestore {
  match /databases/{database}/documents {
    match /performances/{performanceId} {
      allow read, update, delete: if request.auth.uid == resource.data.owner;
      allow create: if request.auth.uid != null;
    }
  }
}

这个想法是,如果你拥有一个性能,你可以读写它;如果你登录,你可以创建一个性能。

此查询工作正常:

db.collection("performances").whereEqualTo(FieldPath.of("owner"), user.getUid())

但是,如果我想获取'场景'子集合的内容,我会收到一个错误:"com.google.firebase.firestore.FirebaseFirestoreException:PERMISSION_DENIED:缺少或权限不足。"这是与以下查询:

db.collection("performances")
            .document(performanceID)
            .collection("scenes");

我假设我需要将查询限制为以下内容,但这不会作为EqualTo是Query而不是集合参考的输出工作,因此我无法访问“文档”:

db.collection("performances")
   .whereEqualTo(FieldPath.of("owner"), user.getUid())
   .document(performanceID)
   .collection("scenes");

那么,如果主集合有安全规则,有人知道我应该如何访问子集合吗?

更新1(因为代码没有在下面的评论中格式化)

我想我可能已经想出了一个解决办法。我没有意识到,默认情况下,我的安全规则会拒绝从子集合读取,因此将其更改为允许在一次演出中对场景进行所有读取和写入,这样就可以正常工作:

service cloud.firestore {
  match /databases/{database}/documents {
    match /performances/{performanceId} {
      allow read, update, delete: if request.auth.uid == resource.data.owner;
      allow create: if request.auth.uid != null;
      
      match /scenes/{sceneId} {
        allow read, write: if true
      }
    }
  }
}

共有1个答案

司徒光霁
2023-03-14

首先,请注意,规则不会层叠,因此您的解决方案实际上会向世界打开所有场景子集合中的所有文档,而不仅仅是父文档的所有者。

您需要使用规则中的get()方法检查父文档的权限。

service cloud.firestore {
   match /databases/{database}/documents {
      match /performances/{performanceId} {
         allow read, update, delete: if request.auth.uid == resource.data.owner;
         allow create: if request.auth.uid != null;

         function parentDoc() {
             return get(/databases/$(database)/documents/performances/$(performanceId)).data;
         }

         match /scenes/{sceneId} {
            allow read, write: if parentDoc().owner = request.auth.uid;
         }
      }
   }
}

在subcollection规则中,我们使用之前捕获的路径段来查找需要检查的父文档。

最后,你可能还想收紧你的create规则。目前,它允许某人创建其他人(或无人)拥有的文档。我怀疑你想要那样。通过检查请求者的id是否在传入文档中,您可以防止潜在的错误,这些错误允许创建用户无法读取的文档:

allow create: if request.auth.uid != null && request.auth.uid == request.resource.data.owner;
 类似资料:
  • 假设我有一个集合,其中包含子集合。餐厅权限设置在餐厅文档中,如下所示: 餐馆 任何有权访问餐厅的人也可以访问它的任何子集合,包括子集合。这是安全规则: 安全规则 查询餐厅列表可以这样完成,而且效果很好: 查询餐厅 现在如何查询子集合?我知道Firestore需要根据查询推断权限,而不查看底层数据。从逻辑上讲,这应该是可能的,因为任何可以访问的人也可以访问子集合。但是我如何组合这个子集合查询,以便F

  • 我想我读到您可以使用新的Firebase Firestore查询子集合,但我没有看到任何示例。例如,我以以下方式设置了Firestore: 舞蹈[收藏] DanceName 歌曲[收藏] 松南 我如何才能查询“查找所有的舞蹈在songName=='x'”

  • 全组合 问题描述 这道题是 LeetCode 78 题 - 子集。 从不含重复元素的 n 个元素中,选择 0~n 个元素,组成一个子集,找出所有的子集(幂集)。 解法一:二进制转换法 如果 n 个元素都不相同,可以使用二进制转换法求得所有的子集。将一个数从 0 开始,每次加 1,一直加到 $2^n-1$,其二进制表示从 000...000 到 111...111,每一位表示对应元素是否被选择。这种

  • 为了查询子集合和父文档,我对firest的文档及其最佳实践有一些问题。我试图使用Typecript在我的Firebase函数中进行查询。 DB: ├── 用户(集合) │ └── 用户(ID为的文档) │ │ └── 计划(子集合) 我有一个数组中的用户ID列表,我需要从用户文档和当前文档的子集合计划中收集信息。 但是如何从用户文档和子集合(计划)文档(当前)中获取数据,我不知道在场景中最有效的查

  • 我有文档,其中包含子集合。现在,我想获取子集合中至少有一项的所有项目。这可能吗? 类似于: < code>getDocs(collection(getDB()," Projects)),其中(" Items.size ","