Firestore:未知Connection ID时查询IntentItem?是否需索引ID字段?
Firestore 跨子集合按ID查询文档问题
文档结构
connections(collection): connection1(docId): ...fields... intentItems(subcollection): intentItem1(docId): ...fields... intentItem2(docId): ...fields... connection2(docId): ...fields... intentItems(subcollection): intentItem3(docId): ...fields... intentItem4(docId): ...fields...
需求与尝试操作
作为管理员,需在未知所属connection文档ID的情况下,通过ID读取intentItem文档,尝试了两种方法:
import {doc, documentId, FieldPath} from "@firebase/firestore"; import {query, where} from "firebase/firestore"; // 报错信息:FirebaseError: Invalid query. When querying a collection group by documentId(), the value provided must result in a valid document path, but 'XXXX' is not because it has an odd number of segments (1). query(collectionGroup(db, Collections.intentItems), where(documentId(), "==", term)) // 返回空结果(规则中用**作为通配符) useDocument(doc(db, Collections.connections, '**', Collections.intentItems, term))
问题
是否必须在intentItem文档中添加id字段并建立索引,才能实现该查询需求?
解决方案
不需要额外添加字段,有两种直接可行的解决方式:
修正集合组查询的写法
之前的集合组查询报错,是因为导入的documentId()函数在集合组查询中匹配的是完整文档路径,而非子文档自身的ID。要匹配子文档ID,需使用FieldPath.documentId(),它会定位到当前集合组内文档的ID。修正后的代码:import {collectionGroup, query, where, FieldPath} from "firebase/firestore"; const q = query( collectionGroup(db, Collections.intentItems), where(FieldPath.documentId(), "==", term) );注意:首次运行该查询时,Firebase控制台会提示创建集合组索引,直接点击链接完成创建即可。
修正安全规则与查询逻辑的匹配
doc()函数不支持**作为通配符,它只能接受具体的文档ID路径,所以第二种方法的写法本身不合法,自然返回空结果。正确做法是用集合组查询,同时确保安全规则允许管理员访问所有intentItems子集合:match /connections/{connectionId}/intentItems/{intentItemId} { allow read: if request.auth.token.admin == true; }
如果你的intentItemID是全局唯一的,第一种方法完全满足需求,无需额外添加字段。只有当需要更复杂的过滤逻辑时,才考虑添加字段建立索引,当前场景下没必要。
内容的提问来源于stack exchange,提问作者tg44
相关产品推荐
相关产品推荐

