Firebase安全规则配置求助:限制arrayRemove仅移除当前用户UID且不修改其他字段
解决Firestore通知记录的安全规则问题
我来帮你搞定这个Firestore安全规则的需求,你的场景很典型——用户只能移除自己的UID,不能碰通知的其他内容,咱们来一步步修正规则:
先分析你原有规则的问题
你用request.resource.size() == 1不生效,是因为Firestore的request.resource代表的是更新后的完整文档状态,而不是你请求里只提交的那一个字段。哪怕你只更新users,request.resource里也会包含原文档的所有字段(比如text),所以size()肯定不是1,这个判断逻辑不对。
正确的安全规则实现
下面是符合你需求的规则,我会逐行解释:
allow update: if // 1. 用户已认证 request.auth.uid != null && // 2. 用户当前在可查看通知的列表中 request.auth.uid in resource.data.users && // 3. 只能修改`users`这一个字段,其他字段完全不能动 request.resource.data.diff(resource.data).affectedKeys().hasOnly(["users"]) && // 4. 确保更新后的users列表,只是原列表移除了自己的UID(不能移除别人的,也不能加东西) request.resource.data.users == resource.data.users.removeAll([request.auth.uid]);
规则细节解释
- 关于只修改users字段:
request.resource.data.diff(resource.data)会生成新旧文档的差异对象,affectedKeys().hasOnly(["users"])能精准检查到只有users字段被修改,完美替代你之前的size()判断,不管原文档有多少字段,只要其他字段没动就符合要求。 - 关于只能移除自己的UID:
resource.data.users.removeAll([request.auth.uid])是Firestore规则里的方法,会返回原列表移除当前用户UID后的结果。对比这个结果和更新后的users列表,就能确保用户只能移除自己的UID——如果用户尝试移除别人的UID,或者用arrayRemove传入多个UID,更新后的列表就会和预期不符,规则会直接拦截。
额外验证
你可以测试几种违规场景,规则都会生效:
- 尝试修改
text字段:diff检查会发现affectedKeys包含text,规则拒绝 - 尝试移除别人的UID:更新后的users列表和
removeAll([自己UID])的结果不一致,规则拒绝 - 未认证用户发起请求:直接被第一条拦截
内容的提问来源于stack exchange,提问作者Franck
相关产品推荐
相关产品推荐

