Firestore 安全规则:如何约束使用 get() 的查询<document_path>?



所以我有一个查询(失败(。它读起来是这样的:";作为我的用户,我可以为一个组织列出我所属的所有业务;。

fs
.collection('businesses')
.where('organizationUid', isEqualTo: 'some-organization-id')
.get();

以及保护它的安全规则(要点(:

match /businesses/{businessId} {
function isStaffOrHigher() {
return get(/databases/$(database)/documents/businesses/$(businessId)/users/$(request.auth.uid)).data.role >= 50;
}
allow read: if isStaffOrHigher();
match /orders/{orderId} {
allow read, write: if isStaffOrHigher();
}
match /users/{userId} {
allow read: if request.auth.uid == userId || isStaffOrHigher();
}
}

基本上,它在用户文档(该企业拥有(中查找用户的角色。这种类型的规则(使用get()运算符(适用于{businessId}的子集合(例如,查询orders没有问题(,但不适用于试图列出业务的查询。

现在我知道organizationUid是一个有效的约束,但读取规则不是过滤器,我可以理解为什么Firestore在不读取大量数据的情况下无法验证这一声明。

问题是,那么我该如何解决这个问题呢?Firestore如何正确验证子集合的约束?

安全规则不会执行您想要的操作,因为它将涉及为查询匹配的每个文档读取另一个文档。规则无法提前知道这些文档将是什么,因为路径中有变量(businessId(。如果这个查询将产生数百万个businesss集合的文档,那么您可以看到从/business/$(businessId(/users/$(request.auth.uid(读取每个匹配的文档以确定是否应该允许拒绝整个查询会有多大问题(而且成本高昂(。

规则必须以极快的速度运行,才能以Firestore所需的方式进行扩展。规则不能是过滤器的限制是可伸缩性要求的一部分。这也是为什么每次规则评估使用get()读取10个文档的总体限制。

从规则的角度来看,除了执行多个查询,每个查询都在每个集合的规则范围内,并在客户端应用程序中合并结果之外,没有其他解决方法。

相关内容

最新更新