如果安全规则参数不是查询的一部分,为什么 firestore 抛出权限被拒绝?

Why does firestore throw permission denied if the security rule parameter is not part of the query?

我知道 collection 中的每个 doc 如果 request.resource.data.foo === bar

request.auth.uidrequest.resource.data.users
// security rule
match /collection/{id}/{document=**} {
   allow read: if request.auth.uid in request.resource.data.users;
}

// does not work
const snapshot = await collectionRef.where("foo", "==", "bar").get()

// works
const snapshot = await collectionRef.where("foo", "==", "bar").where("users", "array-contains", userID).get()

即使 collection 中的每个文档都满足 firestore 抛出的安全规则 permission denied。一旦我添加了额外的用户查询参数子句,查询就可以工作了。

涉及查询字段过滤器的安全规则不检查文档的实际内容。对于大规模 collections,这根本无法扩展。 Firestore 中的每个查询都必须能够大规模扩展。

安全规则的作用是检查查询是否请求规则未明确允许的任何内容。您的规则实际上是在说“不允许任何人在 collection 上进行查询,除非字段 uid 上有一个 array-contains 过滤器,他们提供由 Firebase Auth 验证的实际 uid” .

您的第一个查询没有指定所需的过滤器,因此立即被拒绝。您的第二个查询确实指定了所需的过滤器,因此它通过了。同样,任何文件的内容都无关紧要。

我也建议 reading this part of the documentation carefully