Flutter:Firestore安全规则未生效,权限控制不符合预期
Firestore安全规则不生效的原因及修复方案
核心问题1:全局允许规则覆盖具体限制
你的规则中最顶部的match /{document=**}规则允许所有读写操作直到2023-10-30,Firestore安全规则的逻辑是只要有任意一条匹配的规则允许操作,请求就会被通过。这条全局规则的匹配范围包含所有文档路径,因此即使你在/requests/{item}里设置了佣金限制,请求也会被全局规则直接允许,导致具体限制完全失效。
修复方案
直接删除或注释掉这条全局允许规则:
// 移除这条全局允许规则,避免覆盖后续具体限制 // match /{document=**} { // allow read, write: if request.time < timestamp.date(2023,10, 30); // }
核心问题2:商家删除规则存在语法与逻辑错误
规则中{requestId}是未定义的变量,Firestore无法识别该占位符;同时,Firestore安全规则不支持遍历集合查询,你无法通过单个get()调用检查所有requests文档是否关联当前商家,这就导致删除规则完全不起作用。
修复方案
方案A:通过反向引用验证(推荐)
在businesses文档中添加related_requests_count字段,每当有requests文档关联该商家时,同步更新这个计数;删除商家时,检查计数为0:
match /businesses/{business} { allow delete: if resource.data.related_requests_count == 0; }
需要在Flutter代码中维护这个计数:创建/删除关联的requests文档时,同步增减商家的related_requests_count值。
方案B:使用云函数验证
若不想维护计数,可编写云函数在删除商家前查询所有关联请求,存在关联则阻止删除:
// 云函数示例(Node.js) const functions = require('firebase-functions'); const admin = require('firebase-admin'); admin.initializeApp(); exports.preventBusinessDeleteWithRequests = functions.firestore .document('businesses/{businessId}') .onDelete((snap, context) => { const businessId = context.params.businessId; // 检查business_received关联的请求 return admin.firestore().collection('requests') .where('business_received', '==', businessId) .get() .then(querySnapshot => { if (!querySnapshot.empty) { throw new Error('该商家存在关联请求,无法删除'); } // 检查business_send关联的请求 return admin.firestore().collection('requests') .where('business_send', '==', businessId) .get(); }) .then(querySnapshot => { if (!querySnapshot.empty) { throw new Error('该商家存在关联请求,无法删除'); } return null; }) .catch(err => { // 抛出错误会回滚删除操作 throw err; }); });
同时调整Firestore规则,禁止客户端直接删除商家:
match /businesses/{business} { allow delete: if false; // 仅允许云函数执行删除 }
修复后的完整规则示例
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /requests/{item} { allow create, update, write: if request.resource.data.commision > 0; // 根据实际需求补充读规则 allow read: if true; } match /businesses/{business} { allow delete: if resource.data.related_requests_count == 0; // 根据实际需求补充其他操作规则 allow read: if true; allow create, update: if true; } } }
内容的提问来源于stack exchange,提问作者Dev_flutter
相关产品推荐
相关产品推荐

