Firebase Firestore规则:处理单个文档而不是范围查询,为什么?

Firebase Firestore规则:处理单个文档而不是范围查询,为什么?,firebase,google-cloud-firestore,firebase-security,Firebase,Google Cloud Firestore,Firebase Security,以下是我的Firebase规则的两个版本,在我看来,它们应该是等效的: 版本1: match /transactions/{ts} { function isOwner() { return request.auth.uid == get(/databases/$(database)/documents/transactions/$(ts)).data.user; } allow read: if isOwner(); } 版本2: match /transactions

以下是我的Firebase规则的两个版本,在我看来,它们应该是等效的:

版本1:

match /transactions/{ts} {
  function isOwner() {
    return request.auth.uid == get(/databases/$(database)/documents/transactions/$(ts)).data.user;
  }

  allow read: if isOwner();
}
版本2:

match /transactions/{ts} {
  function isOwner() {
    return request.auth.uid == resource.data.user;
  }

  allow read: if isOwner();
}
现在,如果我查询单个文档,例如
db.collection('transactions').doc(someIDHere)
,这两个规则在接受或拒绝方面的作用完全相同


但是,如果我正在执行一个查询,比如
db.collection('transactions').where('user','==',userid.).get()
,那么只有版本2才能通过,版本1将报告一个错误,但我不知道为什么会出现这种情况。我查看了Firestore文档,但没有足够的解释。特别是,rule语句中的get()方法是什么意思?为什么在范围查询中使用get(绝对路径)与使用resource.data不同?

第二条规则有效,因为过滤器:

where('user','==',userid)
与规则的约束完全匹配:

request.auth.uid == resource.data.user
(我在其中添加了您缺少的“auth”-在
请求上没有
uid
属性)


安全规则不会对与可能返回任意数量文档的集合查询相匹配的每个文档执行
get()
。首先,对于大型结果集,这将无法扩展,其次,每个规则计算只有10个get()的限制。安全规则要做的是检查查询约束是否匹配所有可能匹配的文档的查询。换句话说。客户端上的筛选器必须与规则上的约束相匹配,而无需对每个文档进行评估。

感谢您的解释。我明白为什么第二条规则可以通过,但为什么第一条规则不行,请注意返回的
get(…).data
resource.data
完全相同,因此
where('user','==',userid)
过滤器匹配这两条规则。我知道使用
resource.data
来获取这个值在某种程度上与在引擎盖下使用
get(absolute_path)
不同,尽管它们将返回相同的值,我的问题是它们之间有何区别,以便将来在实际运行规则之前,我可以判断是否会遇到这种错误。get()需要获取文档,但使用安全规则检查客户端筛选器只需要它们匹配即可。因此,如果客户机完全按照规则要求进行过滤,那么它实际上不需要知道文档的内容。不存在需要文档内容的“如果”情况。我明白你的意思,我没有意识到这一点,直接检查过滤器是否符合规则是非常聪明的,谢谢你澄清这一点。