Google cloud firestore 为什么使用get()的Firestore安全规则不起作用,而另一个使用resource.data的规则起作用?
为了适应云Firestore,我一直在开发聊天应用程序。Google cloud firestore 为什么使用get()的Firestore安全规则不起作用,而另一个使用resource.data的规则起作用?,google-cloud-firestore,firebase-security,Google Cloud Firestore,Firebase Security,为了适应云Firestore,我一直在开发聊天应用程序。 下面是它的数据库结构 rooms ├ xxxxxx │ ├ messages │ │ ├ xxxxxx │ │ └ xxxxxx │ └ private │ └ allowed - members [xxxxxxxx, xxxxxxxx] └ xxxxxx ├ messages │ ├ xxxxxx │ └ xxxxxx └ privat
下面是它的数据库结构
rooms
├ xxxxxx
│ ├ messages
│ │ ├ xxxxxx
│ │ └ xxxxxx
│ └ private
│ └ allowed - members [xxxxxxxx, xxxxxxxx]
└ xxxxxx
├ messages
│ ├ xxxxxx
│ └ xxxxxx
└ private
└ allowed - members [xxxxxxxx, xxxxxxxx]
每个聊天室文档下的private
子集合有一个文档,其ID为allowed
。allowed
具有成员
,这是一个数组字段,其中包含允许使用聊天室的用户ID
获取特定聊天室首先要做的是获取允许的
文档,如下所示:
db.collectionGroup('private'))
.where('members','array contains',userId)
.get()
.然后(…)
我已经在private
上为集合组查询创建了一个索引,因此上面的代码可以工作
但是,如果我添加以下安全规则,它将失败,并显示错误消息“Uncaught(in promise)FirebaseError:缺少或权限不足”
match /{path=**}/private/{document} {
allow read: if request.auth.uid
in get(/databases/$(database)/documents/$(path)/private/$(document)).data.members;
}
此规则用于禁止非会议室成员的用户访问允许的。
没有。其中(…)
的查询会导致相同的错误
另一方面,下面的规则按预期工作
match /{path=**}/private/{document} {
allow read: if request.auth.uid in resource.data.members;
}
我知道这个规则要好得多,所以我肯定会使用它,但我仍然想知道为什么以前的规则不起作用。
有人能解释一下原因吗
这可能有任何关系吗?您的安全规则是为collectionGroup/{path=**}/private
编写的,首先,此规则在编写时适用于任何名为“private”的集合,无论它在何处。此外,您还尝试使用变量$(rule)
,我看不到该变量的定义
安全规则仅适用于匹配的查询——您必须确保查询的明确性不会导致不允许的文档。如果查询可能导致不允许的文档(即安全规则指定的文档),则整个查询将被拒绝,而不仅仅是不允许的文档。安全规则要么全有要么全无——这就是它们可以扩展的原因。哎呀,这是我的错。我错误地粘贴了我之前尝试过的规则之一,对不起!实际的get()
部分是get(/databases/$(database)/documents/$(path)/private/$(document)).data.members代码>,这也不起作用。至于规则只对匹配的查询起作用这一事实,我已经注意到了,因此粘贴了相关描述的屏幕截图。我的问题是,为什么它会影响我的查询?我猜其中('members','array contains',userId)
是只获取允许的文档的条件。错了吗?是的,我知道。安全规则可以在.get()中获取一个文档。但是您的查询(上面)可以匹配许多文档,因为${path=**}是/private后面的任何路径,并且collectionGroup查询中的{document}表示一组文档,而不仅仅是一个文档。我遇到过这样的问题(我使用了很多CollectionGroup),它们可能很难纠正安全规则。谢谢!听起来很合理。据我所知,.get(许多文档).data.members
是一种以错误方式从数组中的多个对象获取每个成员
字段的操作;它几乎像[{members:['a',b']},{members:['a',b']}]。members
,这在各种编程语言中都是错误的。您能编辑您的答案,以便我选择它作为最佳答案吗?