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

Firestore安全规则中resource.data始终为空对象是否为Bug?

这不是Bug,是递归路径匹配导致的集合/文档权限区分问题

你遇到的现象并不是Firestore安全规则的Bug,而是因为你使用了递归路径匹配({document=**}),这个匹配规则会同时作用于hospitals集合本身以及它下面的所有文档、子集合。

问题原因拆解

当你执行集合级别的查询(比如db.collection("hospitals").get())时:

  1. 规则会先检查hospitals集合本身的权限,此时resource代表的是集合而非单个文档,集合没有实际数据内容,所以resource.data是空对象。
    • 这就是allow read :if resource.data.size() == 0返回true的原因——集合的resource.data确实是空的。
    • 而resource.data.name != null会返回false,因为空对象里根本没有name字段,导致集合的读取权限被拒绝,整个查询直接失败,哪怕你要读取的文档本身包含name字段。
  2. 只有当你查询单个文档(比如db.collection("hospitals").doc("xxx").get())时,resource才会指向该文档的实际数据,此时resource.data.name != null才会根据文档内容判断是否生效。

解决办法

根据你的需求选择以下两种方案:

方案1:仅匹配hospitals下的直接文档(不含子集合)

如果你的hospitals集合下没有需要权限控制的子集合,把匹配规则改成只针对单个文档:

service cloud.firestore {
  match /databases/{database}/documents {
    match /hospitals/{hospitalId} {
      allow read :if resource.data.name != null;
    }
  }
}

这样规则只会作用于hospitals下的单个文档,集合级查询时会自动检查每个文档的name字段是否存在。

方案2:保留递归匹配,区分集合和文档的权限

如果需要包含子集合的权限控制,你需要在规则中区分集合和文档的情况:

service cloud.firestore {
  match /databases/{database}/documents {
    match /hospitals/{document=**} {
      // 允许读取集合(resource.data为空),同时允许读取存在name字段的文档/子集合文档
      allow read: if resource.data.size() == 0 || resource.data.name != null;
    }
  }
}

这个规则会允许集合级查询通过,同时确保所有被读取的文档都包含name字段。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:41:53