PAYATHON 2026

Flutter 双平台 Firestore permission-denied 如何排查?

数据阿明

结论

如果应用实际访问的 Firestore 数据库已发布 allow read, write: if true;,这条规则不应因 Firebase Authentication 用户身份不匹配而拒绝普通文档读写。先确认应用请求使用的 Firebase 项目、Firestore 数据库和规则版本,再检查 App Check 是否启用了强制执行,并确认失败操作确实发往 Cloud Firestore。

问题中给出的规则允许读写数据库中匹配的文档。Rules Playground 显示成功,只能说明模拟所用的项目、数据库、路径和操作通过了规则评估,不能证明应用运行时请求使用了相同的数据库和规则。

排查步骤

1. 确认应用实际使用的 Firebase 项目和数据库

projectId 相同是有用线索,但还需要确认运行时使用的 Firebase app、Firestore 实例和数据库 ID。如果项目配置了多个 Firestore 数据库,Console 中查看或模拟的数据库可能与应用请求访问的数据库不同。

可以在初始化后打印当前 app 配置,并检查创建 Firestore 实例的代码:

final app = Firebase.app();
print('Firebase app: ${app.name}');
print('Firebase project: ${app.options.projectId}');
print('Firebase app ID: ${app.options.appId}');

final firestore = FirebaseFirestore.instance;

如果应用使用 FirebaseFirestore.instanceFor(...) 或指定了 databaseId,请确认该 ID 对应的是 Console 中检查过的数据库。还要核对 iOS 和 Android 构建实际打包的配置文件及目标 Firebase app。仓库里的配置文件未必就是当前运行包使用的配置。

2. 确认规则已发布到目标数据库

在 Firebase Console 中选择应用实际访问的 Firestore 数据库,检查 Rules 页面显示的已发布规则。确认 match /{document=**} 覆盖正在访问的文档路径,并分别检查读、写操作。

如果刚修改过规则,请再次确认变更已发布到目标数据库。只有当 Rules Playground 的模拟与应用请求使用相同的数据库、文档路径和操作类型时,两者才可以直接比较。

3. 检查 App Check 强制执行状态

如果 Firestore App Check 已启用强制执行,应用请求就需要携带有效的 App Check token。即使 Security Rules 允许访问,请求仍可能被拒绝。请检查 Firebase Console 中该项目的 App Check 指标和 Firestore 强制执行设置,并查看设备日志中是否有 App Check token 获取或验证失败的信息。

排查时不要长期关闭保护。先确认是否启用了强制执行,以及应用是否按预期配置了 App Check provider。

4. 确认失败请求确实来自 Firestore

问题中的日志格式指向 cloud_firestore 插件。仍需对照触发错误的具体调用,确认失败的是 Firestore 读写,而不是同一流程中的其他 Firebase 服务。可以临时记录失败调用对应的集合、文档路径和操作类型,避免只根据页面上显示的错误提示判断。

5. 用最小请求复现并对照日志

在应用内对一个明确路径执行单次写入,并记录该路径、Firebase app 配置和异常详情。然后在 Console 的 Rules Playground 中,对同一数据库、路径和操作进行模拟。如果模拟通过而应用仍然失败,重点检查数据库 ID、运行包配置和 App Check 状态。

注意事项

allow read, write: if true; 会开放匹配数据库中的读写权限,只适合短期测试。排查完成后,应尽快恢复为基于用户身份和数据访问范围的规则。现有信息不足以确定错误的具体原因,需要结合运行时数据库、已发布规则和 App Check 状态继续定位。

备注:内容仅供参考。