我正在构建一个博客,并使用firestore作为数据库。我正在努力编写安全规则,这样只有订阅的用户才能查看文章的内容,但我希望每个人都能在主页上看到文章的标题和照片。
我的数据库模式如下:
我有一个文章集,其中每个文档都是一个单独的文章,其中包含标题和照片等字段。在每个文章文档中都有一个子集合"protected",其中包含文章的内容,我希望只有订阅的用户才能获得受保护的信息。
到目前为止,我的规则是
match /articles/{articleId} {
allow read: if true;
allow write: if request.auth.uid == 'someId';
match /articles/{articleId}/protected/{protecedId} {
allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.subscription == true;
}
}
然而,这会阻止我的主页加载和显示任何文章。有人能帮我弄清楚我的规则出了什么问题吗?
更新时间:我的规则现在是这样的:
match /articles/{articleId} {
allow read: if true;
allow write: if request.auth.uid == 'someid';
match /protected/{protectedId} {
allow read: if true;
allow write;
}
}
然而,我的主页再次没有加载。唯一的解决方案似乎是将match/{document=**}添加到我的规则中。然而,这意味着我的所有其他规则都被覆盖了。
固定:
我需要为我所有的集合和子集合编写规则。
您没有在规则中正确声明分层数据结构。
正如上面链接的文档中所解释的,"当嵌套匹配语句时,内部匹配语句的路径总是相对于外部匹配语句的路径"。
因此,您应该删除/articles/{articleId}/protected/{protectedId}
路径的第一部分,如下所示:
service cloud.firestore {
match /databases/{database}/documents {
match /articles/{articleId} {
allow read: if true;
allow write: ....;
match /protected/{protecedId} {
allow read: if get(/databases/$(database)/documents/users/$(request.auth.uid)).data.subscription == true;
}
}
}
}