我正在努力弄清楚如何为子集合编写 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} 上一样允许它。
请务必记住,规则中的
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;
}