Angular+Firebase如何查询嵌套集合中匹配用户ID的文档?
解决方案:遍历Projects子集合并匹配用户ID
你的代码问题在于集合路径错误:projects/orcamentosRecebidos 会被Firestore解析为根集合projects下的一个文档orcamentosRecebidos,而不是每个projects文档下的子集合。下面提供两种可行方案:
方案一:遍历所有Projects文档,逐个查询子集合
适合Projects文档数量较少的场景,逻辑直观:
async pegarOrcamentosDoUsuario() { const userId = localStorage.getItem('app_auth'); if (!userId) { console.log('Usuário não autenticado'); return []; } // 获取所有projects文档 const projectsSnapshot = await getDocs(collection(this.firestore, 'projects')); const matchingOrcamentos: Array<{id: string, data: any, parentProjectId?: string}> = []; // 遍历每个project文档,查询其下的orcamentosRecebidos子集合 for (const projectDoc of projectsSnapshot.docs) { const orcamentosQuery = query( collection(this.firestore, `projects/${projectDoc.id}/orcamentosRecebidos`), where('id', '==', userId) ); const orcamentosSnapshot = await getDocs(orcamentosQuery); // 收集匹配的文档,可选记录所属项目ID orcamentosSnapshot.forEach(doc => { matchingOrcamentos.push({ id: doc.id, data: doc.data(), parentProjectId: projectDoc.id }); }); } console.log('Orçamentos do usuário:', matchingOrcamentos); return matchingOrcamentos; }
方案二:使用Firestore集合组查询(推荐)
如果所有子集合名称统一为orcamentosRecebidos,集合组查询可以直接搜索所有该名称的子集合,无需遍历Projects文档,效率更高:
async pegarOrcamentosDoUsuario() { const userId = localStorage.getItem('app_auth'); if (!userId) { console.log('Usuário não autenticado'); return []; } // 创建集合组查询,匹配所有orcamentosRecebidos子集合中id等于用户ID的文档 const orcamentosQuery = query( collectionGroup(this.firestore, 'orcamentosRecebidos'), where('id', '==', userId) ); const querySnapshot = await getDocs(orcamentosQuery); // 整理结果,从文档路径中提取所属项目ID const matchingOrcamentos = querySnapshot.docs.map(doc => ({ id: doc.id, data: doc.data(), parentProjectId: doc.ref.path.split('/')[1] })); console.log('Orçamentos do usuário:', matchingOrcamentos); return matchingOrcamentos; }
注意事项
使用集合组查询需要先创建对应的索引:
- 首次运行代码时,控制台会输出一个错误链接
- 点击链接,Firebase控制台会自动填充索引创建表单
- 确认创建索引,等待几分钟生效即可
内容的提问来源于stack exchange,提问作者André
相关产品推荐
相关产品推荐

