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

Flutter中Firestore安全规则权限拒绝问题求助

问题分析与解决

问题背景

使用Firebase Firestore存储数据,设置的安全规则要求:仅当用户认证UID存在于目标文档的userSessions数组中时,才允许访问该文档。安全规则代码如下:

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /mock_text/{document}/{path=**} {  
      allow read, write: if 
        request.auth.uid in get("/databases/$(database)/documents/mock_text/$(document)/").data.userSessions;
    }
  }
}

通过后端维护userSessions列表,功能正常。在Flutter应用中使用匿名认证,执行以下查询时触发权限拒绝错误:

final query = _firestore
    .collection("mock_text")
    .where("userSessions", arrayContains: currentUser!.uid);

错误信息:

FirebaseException ([cloud_firestore/permission-denied] The caller does not have permission to execute the specified operation.)

已确认Firestore与Auth连接正常(将规则改为request.auth.uid != null可正常运行),且规则在Firestore测试平台中验证有效。

问题根源

当前安全规则使用get()调用获取目标文档数据来验证权限,这种方式仅适用于单个文档的读写操作(比如doc("xxx").get())。但在执行集合查询时,Firestore需要提前判断整个查询是否符合规则,无法为每个待匹配的文档单独执行get()操作(存在性能和安全限制),因此会直接返回权限拒绝。

解决方案

1. 修改安全规则

将规则中的get()调用替换为直接访问当前文档的resource对象,resource代表当前正在被访问的文档,在集合查询场景下可以直接读取其数据:

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /mock_text/{document}/{path=**} {  
      allow read, write: if 
        request.auth != null && request.auth.uid in resource.data.userSessions;
    }
  }
}

添加request.auth != null的前置检查,避免未认证用户触发不必要的验证逻辑。

2. 保留现有Flutter查询逻辑

你的Flutter查询代码是正确的,where("userSessions", arrayContains: currentUser!.uid)会筛选出包含当前用户UID的文档,和修改后的规则逻辑完全匹配,无需调整。

验证

修改规则后,重新执行Flutter查询即可正常获取数据。若仍有问题,可检查:

  • 当前用户的UID确实存在于目标文档的userSessions数组中
  • 匿名认证已成功完成,currentUser不为空

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 13:45:18