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

Firestore REST API集合查询权限报错及文档ID过滤、路径限制疑问

Firestore REST API 查询权限与范围问题

我的Firestore数据库结构如下:

/collection1/<docid1>/collection2/<docid2>/field1 (authenticated user)
/collection3/<docid2>/field2 (restricted access)

需求是仅获取collection1下collection2中field1为特定值的所有文档。我在查询构建器中使用「Collection group」,过滤「Document Id」和field1可实现该查询,但通过REST API的:runQuery提交以下结构化查询时:

{
  "structuredQuery": {
    "from": [{
      "allDescendants": true,
      "collectionId": "collection2"
    }],
    "orderBy": [{
      "direction": "ASCENDING",
      "field": {
        "fieldPath": "field3"
      }
    }],
    "where": {
      "compositeFilter": {
        "filters": [{
          "fieldFilter": {
            "field": {
              "fieldPath": "field1"
            },
            "op": "EQUAL",
            "value": {
              "stringValue": "<something>"
            }
          }
        }, {
          "fieldFilter": {
            "field": {
              "fieldPath": "uid"
            },
            "op": "LESS_THAN",
            "value": {
              "stringValue": "/collection1/z"
            }
          }
        }, {
          "fieldFilter": {
            "field": {
              "fieldPath": "uid"
            },
            "op": "GREATER_THAN",
            "value": {
              "stringValue": "/collection1/0"
            }
          }
        }],
        "op": "AND"
      }
    }
  }
}

始终返回403权限错误:

"error": {
   "code": 403,
   "message": "Missing or insufficient permissions.",
   "status": "PERMISSION_DENIED"
}

安全规则(仅展示读取权限):

rules_version = '2';

service cloud.firestore {
  match /databases/{database}/documents {
    match /collection1/{docid1} {
      allow read: if request.auth != null;
      match /collection2/{docid2} {
        allow read: if request.auth != null;
      }
    }
    match /collection3/{docid2} {
      allow read: if request.auth != null && request.auth.uid == docid2;
    }
  }
}

疑问解答

1. uid是否等同于查询构建器中的「Document ID」?若不等同,如何在REST API中按「Document ID」过滤?

  • uid不等同于Document ID,它是Firebase Auth用户的唯一标识符,和文档ID无直接关联。
  • 在REST API的结构化查询中,按文档ID过滤需使用特殊字段路径__name__,代表文档的完整资源名称。示例如下:
    匹配特定文档ID:
    {
      "fieldFilter": {
        "field": {
          "fieldPath": "__name__"
        },
        "op": "EQUAL",
        "value": {
          "referenceValue": "projects/[你的项目ID]/databases/(default)/documents/collection1/[docid1]/collection2/[目标docid2]"
        }
      }
    }
    
    匹配父集合文档ID的范围:
    {
      "fieldFilter": {
        "field": {
          "fieldPath": "__name__"
        },
        "op": "GREATER_THAN_OR_EQUAL",
        "value": {
          "stringValue": "projects/[你的项目ID]/databases/(default)/documents/collection1/0"
        }
      },
      "fieldFilter": {
        "field": {
          "fieldPath": "__name__"
        },
        "op": "LESS_THAN",
        "value": {
          "stringValue": "projects/[你的项目ID]/databases/(default)/documents/collection1/z"
        }
      }
    }
    

2. 能否将查询范围限制仅在/collection1路径下,避免搜索到/collection3下的collection2?

  • 可以,无需使用allDescendants: true,直接指定collection1作为父路径来限定查询范围,修改from部分如下:
    "from": [{
      "collectionId": "collection2",
      "parent": "projects/[你的项目ID]/databases/(default)/documents/collection1"
    }]
    
    这样查询只会遍历collection1下所有子文档中的collection2子集合,不会涉及collection3路径。
  • 此前的403错误大概率是因为allDescendants: true导致查询尝试访问collection3下的collection2(若存在),而该路径的安全规则要求request.auth.uid == docid2,未满足条件触发权限拦截。限定查询范围后即可避免该问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 07:53:09