Firebase Firestore如何限制集合文档数?非App Check方案及安全疑问
限制Firebase Firestore集合文档数量的可行方案
针对你提到的问题,核心解决思路是用计数器文档配合严格的安全规则,同时从规则层面彻底锁死计数器的篡改可能,确保只有合法的文档增删操作才能触发计数器更新。
具体实现步骤
设计计数器存储结构
在Firestore中创建一个固定路径的计数器文档,比如metadata/counter,用count字段记录目标集合的文档总数。编写安全规则,双向限制操作
规则需要同时约束两个行为:集合的文档增删、计数器的写入,确保两者必须绑定执行,且计数器的更新逻辑完全可控。示例规则(假设目标集合为
posts,阈值设为100):rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // 目标集合的操作规则 match /posts/{postId} { // 创建文档:计数器未达阈值,且必须和计数器+1操作放在同一个批量写入 allow create: if get(/databases/$(database)/documents/metadata/counter).data.count < 100 && request.writeSize == 2 && getAfter(/databases/$(database)/documents/metadata/counter).data.count == resource.data.count + 1; // 删除文档:必须和计数器-1操作放在同一个批量写入 allow delete: if request.writeSize == 2 && getAfter(/databases/$(database)/documents/metadata/counter).data.count == resource.data.count - 1; } // 计数器文档的写入规则:仅允许合法的+1/-1更新,且对应集合文档状态匹配 match /metadata/counter { allow write: if // 创建文档时的计数器更新:新文档存在,计数器+1 (request.resource.data.count == resource.data.count + 1 && exists(/databases/$(database)/documents/posts/$(request.writeIds[0]))) || // 删除文档时的计数器更新:文档已不存在,计数器-1 (request.resource.data.count == resource.data.count - 1 && !exists(/databases/$(database)/documents/posts/$(request.writeIds[0]))); } } }
规则核心逻辑说明
- 绑定批量写入:要求创建/删除文档必须和计数器更新放在同一个批量请求(
writeSize == 2),恶意用户无法单独创建文档或篡改计数器。 - 计数器更新校验:强制计数器只能做+1或-1的操作,且必须对应集合文档的实际增删状态,彻底阻断直接修改计数器的可能。
- 阈值拦截:创建文档前先检查计数器数值,超过阈值直接拒绝。
额外辅助防护措施
- 限制单用户写入频率:通过记录用户最近的写入时间,规则中限制用户每分钟只能写入一次,防止短时间内批量提交请求:
allow create: if ... && request.time > get(/databases/$(database)/documents/user-logs/$(request.auth.uid)).data.last_write + duration.value(1, 'm'); - 校验文档内容:在规则中验证写入的文档字段是否符合预期,避免恶意提交垃圾数据占用集合空间。
内容的提问来源于stack exchange,提问作者Rodent
相关产品推荐
相关产品推荐

