在Firestore安全规则中创建新文档时,如何验证其他文档参考

时间:2019-05-03 13:00:09

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

我目前正在建立一个包含用户和博客文章的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);

经历了很多次反复试验,其背后的逻辑对我来说是丢失的。

1 个答案:

答案 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