如何根据父文档正确授予所有子集合权限

问题描述 投票:0回答:1

我正在努力弄清楚如何为子集合编写 Firestore 规则,我认为这应该是可行的,但我一直被拒绝许可。

我有以下结构

/mycollection/{mainDocument}/subcollection/{subDocument}

里面

{mainDocument}
是成员列表。如果您的UID在该列表中,则您有权读/写该文档以及所有子集合文档

为了验证我的 if 条件是否有效,我有以下规则,该规则适用于主文档,但不适用于子集合。我可以读取和写入此文档并更改其中的成员

match /mycollection/{mainDocument} {
     allow read, write: if request.auth.uid in resource.data.members;
}

文档说,如果您在rule_version = 2上使用递归通配符,它将适用于任何子集合,并且他们给出了这个示例。

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    // Matches any document in the cities collection as well as any document
    // in a subcollection.
    match /cities/{city}/{document=**} {
      allow read, write: if <condition>;
    }
  }
}

当我尝试使用递归通配符时,当我尝试读取或写入子集合时,我的权限被拒绝?

rules_version = '2';
service cloud.firestore {
    match /databases/{database}/documents {

        match /mycollection/{mainDocument}/{document=**} {
            allow read, write: if request.auth.uid in resource.data.members;
        }
    }
}

rules_version = '2';
service cloud.firestore {
    match /databases/{database}/documents {

        match /mycollection/{mainDocument=**} {
            allow read, write: if request.auth.uid in resource.data.members;
        }
    }
}

如果为子集合添加显式规则,那么它可以工作,但我不能在其中使用 if 语句,因为成员列表不在该子集合中。

rules_version = '2';
    service cloud.firestore {
        match /databases/{database}/documents {

            match /mycollection/{mainDocument} {
                allow read, write: if request.auth.uid in resource.data.members;
            }

            match /mycollection/{mainDocument}/subcollection/{subDocment} {
                allow read, write
            }
        }
    }
}

所以我知道我的规则 if open 可以适用于每个集合,但我无法获得在子集合上应用的权限,只能像在 {mainDocument} 上一样允许它。

google-cloud-firestore firebase-security
1个回答
0
投票

请务必记住,规则中的

resource
指的是正在读取或写入的特定文档。因此,当子集合中的文档触发此规则时:

        match /mycollection/{mainDocument}/{document=**} {
            allow read, write: if request.auth.uid in resource.data.members;
        }

resource
指的是子集合中的文档,而不是
{mainDocument}
匹配的文档。完全没有考虑
{mainDocument}
的内容

您应该做的是使用

get()
访问特定文档,其内容必须用于评估规则。像这样的东西:

        match /mycollection/{mainDocument}/{document=**} {
            allow read, write: if request.auth.uid in get(/databases/$(database)/documents/mycollection/$(mainDocument)).data.members;
        }
© www.soinside.com 2019 - 2024. All rights reserved.