Firestore规则验证likes字段size为0时权限被拒求助
Firestore安全规则验证空likes字段时触发权限拒绝错误排查
问题背景
我在配置Firestore安全规则时遇到了一个困扰:当添加规则条件request.resource.data.likes.size() == 0来验证用户提交的likes(map类型)元素数量为0时,应用执行帖子创建操作会触发[cloud_firestore/permission-denied]权限拒绝错误;但删除这个条件后,操作就能正常执行。
我的安全规则代码:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /posts/{post} { allow read :if request.auth != null; allow create : if request.auth.token.firebase.sign_in_provider != 'anonymous' && request.resource.data.uid == request.auth.uid && request.resource.data.size() == 8 && request.resource.data.hasOnly(['withPhoto','uid', 'text', 'tags','imageUrl', 'imageThump', 'comments', 'likes']) && request.resource.data.likes.size() == 0; } } }
帖子创建代码(Flutter):
Set<String> tags = _getTags(postText.toString().split(' ')); FirebaseFirestore firestore = FirebaseFirestore.instance; await firestore.doc("posts/" + uuid).set({ "uid" : uid, "likes":{}, "comments":{}, "tags": tags.toList(), "text": postText, "imageUrl": imageUrl, "imageThump": imageThumpUrl, "withPhoto": withPhoto });
问题原因
核心问题在于Firestore规则对空Map的处理逻辑:当你在客户端传入{}作为likes的值时,Firestore规则并不会将其识别为一个size()为0的Map对象。实际上,客户端提交的空Map在规则层面可能被解析为"字段存在但值为空",但size()方法对于空Map的行为并不像你预期的那样返回0——甚至可能因为类型解析的问题,导致这个条件直接不成立。
解决方案
你需要修改规则中验证空Map的方式,Firestore规则提供了更可靠的方法来检查空Map:
1. 直接验证字段等于空Map
将规则中的request.resource.data.likes.size() == 0替换为:
request.resource.data.likes == {}
2. 或者使用isEmpty()方法
Firestore的Map类型内置了isEmpty()方法,专门用来检查是否为空:
request.resource.data.likes.isEmpty()
修正后的完整安全规则
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { match /posts/{post} { allow read :if request.auth != null; allow create : if request.auth.token.firebase.sign_in_provider != 'anonymous' && request.resource.data.uid == request.auth.uid && request.resource.data.size() == 8 && request.resource.data.hasOnly(['withPhoto','uid', 'text', 'tags','imageUrl', 'imageThump', 'comments', 'likes']) && request.resource.data.likes == {}; } } }
额外优化建议
- 可以额外验证
likes的类型,确保客户端传入的确实是Map:request.resource.data.likes is map,避免非Map类型导致的验证失败。 - 对于
comments字段,建议应用同样的验证逻辑,保持规则的一致性。
内容的提问来源于stack exchange,提问作者SALMAN ABOHOLIQAH
相关产品推荐
相关产品推荐

