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

Firestore查询含当前用户的Workspaces集合权限问题求助

解决Firestore查询包含当前用户的Workspace问题

核心问题

Firestore的安全规则不会事后过滤查询结果,而是要求客户端查询必须只能返回符合规则的文档。你的安全规则允许读取uid在resource.members.keys()中的文档,所以客户端查询必须明确过滤出满足该条件的文档,否则会触发权限错误。

正确的客户端查询方式

在Kotlin/Android中,有两种可靠的方式查询包含当前用户UID作为members键的Workspace文档:

方式1:字符串拼接字段路径

val currentUid = FirebaseAuth.getInstance().currentUser?.uid ?: return
val workspacesCollection = FirebaseFirestore.getInstance().collection("Workspaces")

workspacesCollection
    .whereNotEqualTo("members.$currentUid", null)
    .get()
    .addOnSuccessListener { snapshot ->
        // 遍历符合条件的Workspace文档
        for (doc in snapshot.documents) {
            // 处理文档数据
        }
    }
    .addOnFailureListener { e ->
        // 处理查询错误
    }

方式2:使用FieldPath构造路径(推荐,避免特殊字符问题)

如果UID包含.等特殊字符,用FieldPath更安全:

val currentUid = FirebaseAuth.getInstance().currentUser?.uid ?: return
val memberFieldPath = FieldPath.of("members", currentUid)
val workspacesCollection = FirebaseFirestore.getInstance().collection("Workspaces")

workspacesCollection
    .whereNotEqualTo(memberFieldPath, null)
    .get()
    .addOnSuccessListener { snapshot ->
        // 处理结果
    }

为什么之前的尝试无效

  • whereArrayContains("members.keys", uid):members是Map类型,不是数组,members.keys不是Firestore可识别的字段路径,该查询语法不合法。
  • 交换键值(邮箱作键、UID作值):未同步修改安全规则,原规则是检查UID是否在members.keys()中,交换后规则与数据结构不匹配,自然报错。
  • orderBy("memebers.uid"):首先拼写错误(应为members.uid),其次该查询仅做排序,未过滤文档,会返回所有Workspace,而安全规则会拦截不符合条件的文档,触发权限错误。控制台能运行是因为默认绕过安全规则(项目所有者权限),客户端不具备此权限。

确认安全规则正确性

确保你的安全规则与查询逻辑一致,示例规则如下:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /Workspaces/{workspaceId} {
      allow read: if request.auth != null && request.auth.uid in resource.data.members.keys();
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 08:56:08