【问题标题】:Firestore rules: How do I allow access to a subcollection depending on a field of the document that contains it?Firestore 规则:如何根据包含它的文档的字段允许访问子集合?
【发布时间】:2024-05-23 08:50:02
【问题描述】:

我正在编写一个管理各种联盟的小程序。

我遇到的问题是如何允许正确的用户访问(读取、写入)联赛的比赛日。比赛日被命名为“matchday-1”、“matchday-2”等,是文档(比赛)的集合,是联赛内部的子集合。

我的 firebase 结构 基本上是这样的: 联赛(收藏)-> 联赛(文档)-> matchday-n(收藏)-> match-m(文档) 其中 n 和 m 是数字。

这是问题:

联赛文档包含一个名为“creator”的字段,其中包含创建该联赛的用户的 ID。只有他们才能访问它及其比赛日!

但看起来,当我访问比赛日时,firebase 规则中resource.data.creator 的值与我访问联赛本身时不同。

我的问题是:我必须实施哪条规则,以便只有创建联盟的用户才能访问它及其子集合?

我试图找到一种方法将request.auth.uid 与联盟的创建者进行比较。

我尝试了这样的条件: request.auth.uid == get("path-to-league").creator ,正如您在我提供的代码中看到的那样。 但它似乎并没有以这种方式工作,因为我可能错误地引用了路径。

这是我目前的代码:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /leagues/{league} {
      allow read, write: if request.auth.uid == resource.data.creator
      }
    match /leagues/{league}/{document=**} {
        allow read, write: if request.auth.uid == get(/databases/$(database)/documents/leagues/$(league)).creator
    }
  }
}

取决于我如何修改规则集,但如果是我提供的代码,当我尝试访问(读取或写入)具有错误创建者的联盟时,我会得到“权限缺失或权限不足”,这很好,但即使是正确的创建者,我也无法访问比赛日。

【问题讨论】:

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


    【解决方案1】:

    您缺少一些语法。应该是这样的:

    match /leagues/{league}/{document=**} {
        allow read, write: if request.auth.uid ==
            get(/databases/$(database)/documents/leagues/$(league)).data.creator
    }
    

    请注意,creator 之前有一个 data 属性。这使您可以访问文档资源对象的原始字段值。

    【讨论】:

    • 谢谢!这就是我正在寻找的语法。它有效!
    • 这将创建一个额外的“读取”请求,增加成本.. 仅供参考
    最近更新 更多