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

Firestore规则配置疑问:安全规则适配与写入权限拒绝排查

Firestore规则配置与写入权限问题解决

问题分析

第一个规则的安全隐患

你之前使用的规则:

service cloud.firestore {
  match /databases/{database}/documents {
    match /Users/{document} {
      allow read, write: if request.auth.uid != null;
    }
  }
}

存在严重安全漏洞:任何已认证用户都能读写所有Users集合下的文档,包括修改或删除其他用户的数据,完全违背了用户数据隔离的基本需求。

第二个规则的写入失败原因

你后续使用的规则:

service cloud.firestore {
  match /databases/{database}/documents {
    // Allow public read access, but only content owners can write
    match /Users/{document} {
      allow read: if true;
      allow write: if request.auth.uid == request.resource.data.author_uid;
    }
  }
}

写入失败有两个核心原因:

  1. 请求数据缺失author_uid字段:你的代码仅向map中添加了name字段,未传入规则要求的author_uid,导致规则判断时该字段不存在,直接不满足写入条件。
  2. 规则未绑定文档ID与用户UID:当前规则允许用户写入任意Users文档(只要文档内author_uid等于自身UID),存在用户恶意修改他人文档的风险,同时也不符合你仅操作自身文档的需求。

解决方案

方案1:通过文档ID绑定用户(推荐)

直接将Users集合下的文档ID设为用户的认证UID,规则通过文档ID与当前用户UID的匹配来控制权限,既安全又简洁:

修正后的Firestore规则

service cloud.firestore {
  match /databases/{database}/documents {
    match /Users/{userId} {
      // 允许公开读取(若无需公开读,可改为if request.auth.uid != null)
      allow read: if true;
      // 仅允许文档ID对应的用户执行写入操作
      allow write: if request.auth.uid == userId;
    }
  }
}

对应代码(无需修改现有代码)

你已经使用auth.getCurrentUser().getUid()作为文档ID,刚好符合规则要求,直接运行即可:

name = edit_name.getText().toString();
HashMap<Object, String> map = new HashMap<>();
map.put("name", name);
db.collection("Users").document(auth.getCurrentUser().getUid()).set(map);

方案2:保留author_uid字段的规则(适合需额外字段验证的场景)

若你必须通过author_uid字段验证,需在代码中传入该字段,同时规则需强化文档操作的合理性:

修正后的Firestore规则

service cloud.firestore {
  match /databases/{database}/documents {
    match /Users/{document} {
      allow read: if true;
      // 写入需满足:用户已认证、author_uid匹配当前用户UID、文档ID与用户UID一致
      allow write: if request.auth.uid != null 
                    && request.resource.data.author_uid == request.auth.uid
                    && request.auth.uid == document;
    }
  }
}

修正后的写入代码

在map中添加author_uid字段,值为当前用户的UID:

name = edit_name.getText().toString();
String currentUid = auth.getCurrentUser().getUid();
HashMap<Object, String> map = new HashMap<>();
map.put("name", name);
map.put("author_uid", currentUid);
db.collection("Users").document(currentUid).set(map);

额外安全建议

  • 若无需公开Users数据,将allow read的条件改为request.auth.uid == userId(对应方案1),确保只有用户自身能读取自己的数据。
  • 避免使用allow read/write: if true这类完全开放的规则,除非你明确需要将所有数据公开。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 21:25:28