You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Firestore更新权限拒绝问题:仅允许修改name和photo字段

解决Firestore update()方法权限被拒的问题

嘿,这个问题我之前也碰到过,核心是你对Firestore安全规则里的request.resource和request.data的区别理解错了,导致update操作触发了权限限制。

问题出在哪?

你当前的规则里,update操作要求request.resource.data.size() == 2,还要求它的keys必须包含name和photo。但要注意:

  • 当调用set()方法时,request.resource.data就是你传入的完整文档数据,所以满足size为2的条件;
  • 但调用update()时,request.resource.data是更新后的整个文档数据,它包含原来文档里的所有字段,再加上你这次更新的字段。如果你的用户文档原本就有其他字段(比如createdAt、email之类的),那size() == 2肯定不成立,直接触发PERMISSION_DENIED。

另外,hasAll(['name', 'photo'])也不是你想要的逻辑——它要求文档必须有这两个字段,但你真正想限制的是用户只能修改这两个字段,不能碰其他字段,对吧?

修正后的安全规则

下面是调整后的规则,完美适配你的需求:

service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{user} {
      allow read: if request.auth.uid == user;
      allow update: if 
        request.auth.uid == user &&
        // 限制本次更新只能提交name和photo字段,不能加其他字段
        request.data.keys().hasOnly(['name', 'photo']) &&
        // 验证提交的字段类型正确(支持只更新其中一个的场景)
        (('name' in request.data) => request.data.name is string) &&
        (('photo' in request.data) => request.data.photo is string);
    }
  }
}

规则细节解释

  • request.data:这个才是你调用update()时传入的字段集合,而不是整个文档。用hasOnly确保用户不能提交这两个字段之外的任何数据,完全符合你“禁止输入其他数据”的要求。
  • 类型验证的条件写法:(('name' in request.data) => request.data.name is string),意思是只有当本次更新包含name字段时,才需要验证它是字符串类型。这样用户可以选择只更新name,或者只更新photo,或者两个一起更,都能通过验证。
  • 如果你非要强制用户每次更新必须同时改两个字段,那可以把hasOnly换成hasAll,然后把类型验证改成request.data.name is string && request.data.photo is string,但个人不建议这么做,太死板了。

你的Java代码不用改

你写的Java更新逻辑是对的,传入的Map只有name和photo两个字段,完全符合修正后的规则,现在再调用update()应该就能正常成功了。


内容的提问来源于stack exchange,提问作者batyrf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:37:47