我目前正在建立一个包含用户和博客文章的Firestore数据库。每个博客文章都有对创建它的用户的引用。
我想使用安全规则来确保只有当前经过身份验证的用户才能创建,更新和删除他所写的博客。
以下安全规则为更新和删除启用了此功能:
allow write: if resource.data.user == /databases/$(database)/documents/users/$(request.auth.uid);
但是,这对于 creates 而言不是可行的安全规则,因为资源对象在创建时不存在。因此,它将为我提供一个空指针。
我尝试使用request.resource.data.user代替它,因为它应该等效于resource.data.user,但对于将创建 的文档:< / p>
allow create: if request.resource.data.user == /databases/$(database)/documents/users/$(request.auth.uid);
不幸的是,该规则仅返回而不允许所有创建,而不会通知我出了什么问题。
有人知道如何使用与第一个代码段相同的功能来制定安全规则,但是将其附加到 creates 后可以正常工作吗?
编辑:
我的“用户”和“帖子”集合都是根级别的集合。每个“帖子”都有一个名为“用户”的字段,该字段的类型为 reference 。
如果我可以提取“用户”字段的“ uid”部分并将其与登录用户的uid进行比较,则可以解决问题。
如果我知道如何将整个“用户”字段与另一个集合中的文档进行比较,那也很好。到目前为止,这是我一直试图做的事。
已解决:
显然
allow create: request.resource.data.author.path == /users/$(request.auth.uid);
是 create 的等价物
allow write: if resource.data.user == /databases/$(database)/documents/users/$(request.auth.uid);
经历了很多次反复试验,其背后的逻辑对我来说是丢失的。
答案 0 :(得分:1)
您的规则在语法和语义上都是错误的,这很可能解释了为什么失败。
首先,您不能仅在规则中包含文档的路径。如果您想阅读该文档,则需要使用get()
来调用它;并且如果要检查它是否存在,则需要使用exists()
对其进行调用。
例如:假设您只希望用户在有用户个人资料文档的情况下创建帖子,则可以使用以下方法进行操作:
allow create: if exists(/databases/$(database)/documents/users/$(request.auth.uid));
但是在您的情况下,您似乎正在尝试将发出请求的用户的UID与用户个人资料文档进行比较。当前规则的问题是,您正在尝试将请求的UID与整个用户个人资料文档进行比较,而该文档将永远无法使用。您只能比较值,因此必须将其与配置文件文档中的字段进行比较。
allow create: if request.resource.data.user ==
get(/databases/$(database)/documents/users/$(request.auth.uid)).data.uid;
有关另一个示例,请参见Access other documents。