Firestore如何仅获取文档ID而非数据?受限后如何维护ID集合?
Firestore 仅获取文档ID及维护ID集合方案
1. 是否可以仅获取文档ID?
目前Firestore没有提供直接只返回文档ID的API。你当前的代码调用get()获取集合时,确实会加载完整的文档快照(包括所有数据),即便你只提取ID,仍会产生完整文档的读取费用。
不过可以通过投影查询大幅降低成本:给主集合的每个文档添加一个与文档ID一致的字段(比如docId),然后查询时仅选择该字段,这样读取的数据量极小,费用也会显著降低。示例代码:
const querySnapshot = await db .collection("myCollection") .select("docId") // 仅请求docId字段 .get(); const ids = querySnapshot.docs.map(doc => doc.data().docId);
2. 维护ID跟踪集合的最佳实践
如果投影查询仍不符合需求,维护一个单独的ID集合是可行方案,以下是最佳实践:
- 轻量化设计:ID集合中的文档只保留必要信息,比如仅存储与主集合一致的文档ID(甚至可以是空文档,用文档ID本身作为标识),避免冗余数据占用空间和增加费用。
- 权限同步:给ID集合设置与主集合匹配的安全规则,确保用户只能访问他们有权限查看的ID,避免信息泄露。
- 分页处理:如果ID数量庞大,获取ID集合时同样使用分页(
limit()+startAfter()),避免一次性读取过多数据导致性能问题和高额费用。 - 自动化同步:通过Cloud Functions自动同步主集合的增删操作,避免手动维护带来的不一致问题。
3. Cloud Functions 自动维护ID集合的支持
Firebase完全支持用Cloud Functions的Firestore触发器自动维护ID集合,通过onCreate、onDelete钩子即可实现同步:
示例代码(Node.js):
const functions = require("firebase-functions"); const admin = require("firebase-admin"); admin.initializeApp(); // 主集合新增文档时,同步创建ID集合文档 exports.addDocIdToCollection = functions.firestore .document("myCollection/{docId}") .onCreate(async (snap, context) => { const docId = context.params.docId; // 可以选择存储ID字段,或者直接创建空文档 await admin.firestore().collection("myCollection_ids").doc(docId).set({ id: docId }); }); // 主集合删除文档时,同步删除ID集合对应文档 exports.removeDocIdFromCollection = functions.firestore .document("myCollection/{docId}") .onDelete(async (snap, context) => { const docId = context.params.docId; await admin.firestore().collection("myCollection_ids").doc(docId).delete(); });
部署上述函数后,主集合的增删操作会自动同步到ID集合,无需手动干预。
内容的提问来源于stack exchange,提问作者nwarp
相关产品推荐
相关产品推荐

