Firestore:集合用户中的访问文档具有以下权限:

时间:2019-05-24 16:00:02

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

我有一个用于存储数据的集合,称为公告。但是,每个文档都有一个名为“ permissions”的字段,其中包含一个权限级别字符串。我编写了函数来根据用户的权限级别和资源的权限来确定用户是否具有访问权限。

当我为应该正常工作的单个文档设置onSnapshot回调时,得到响应。一旦将其切换到获取集合的快照,它将收到无效的权限错误。根据我的发现,如果用户无法访问集合中的任何文档,firestore就会失败。我应该使用哪种模型?如何获得用户也应该访问的文档?

规则

match /chapters/{chapter} {
        function isMember() {
          return exists(/databases/$(database)/documents/chapters/$(chapter)/members/$(request.auth.uid))
      }

      function getUser() {
        return get(/databases/$(database)/documents/chapters/$(chapter)/members/$(request.auth.uid))
      }

      function hasPermission(userPermission, documentPermission) {
        return documentPermission == "all" || userPermission == "admin" || userPermission == documentPermission
      }

        allow read: if isMember()

      match /announcements/{announcement} {
        allow read: if isMember() && hasPermission(getUser().data.permissions, resource.data.permissions)
      }
}

Works vvv

firestore.collection("chapters").doc("chapter-1").collection("announcements").doc("doc1").onSnapshot(doc => {
                const announcements = doc.data()

                console.log(announcements)
        })

无法使用vvv

 firestore.collection("chapters").doc("chapter-1").collection("announcements").onSnapshot(docs => {
            docs.forEach(doc => {
                const announcements = doc.data()

                console.log(announcements)
            })
        })

1 个答案:

答案 0 :(得分:1)

这是因为在查询的情况下,规则未过滤

doc

所述
  

在编写查询以检索文档时,请记住安全性   规则不是过滤器-查询是全部还是全部。

您需要“编写查询以符合安全规则的约束条件”

另一方面

  

此行为适用于检索一个或多个文档的查询   从集合中提取,不提取到单个文档。当你   Cloud Firestore使用文档ID检索单个文档   文档并使用您的安全规则评估请求,并   实际的文档属性。

这就是为什么当您使用

只查询一个文档时它起作用的原因

firestore.collection("chapters").doc("chapter-1").collection("announcements").doc("doc1").onSnapshot()


因此,要查询集合,您需要向查询中添加过滤器,如下所示:

firestore.collection("chapters").doc("chapter-1").collection("announcements").where("permissions", "==", "xxxxx");