如何根据设备序列号查找所属Firestore用户文档ID?
根据序列号查找所属用户文档ID的Firestore解决方案
最优方案:集合组查询(推荐)
因为所有用户下的子集合都叫devices,用Firestore的集合组查询可以直接定位到匹配序列号的设备文档,再回溯获取父级用户ID,效率远高于遍历所有用户。
代码示例
const targetSerialNumber = "你要查找的目标序列号"; // 针对所有名为devices的子集合执行查询 firestoreDb.collectionGroup("devices") .where("serial number", "==", targetSerialNumber) .get() .then(querySnapshot => { if (!querySnapshot.empty) { // 每个用户的devices集合只有一个文档,直接取第一个匹配项 const deviceDoc = querySnapshot.docs[0]; // 通过文档引用回溯到父级用户文档,获取ID const userId = deviceDoc.ref.parent.parent.id; console.log("匹配的用户文档ID:", userId); } else { console.log("未找到对应序列号的设备"); } }) .catch(error => { console.error("查询失败:", error); });
注意事项
首次执行该查询会报错,因为需要为集合组devices的serial number字段创建索引。Firestore控制台会直接给出创建索引的链接,点击跳转完成创建即可。
备选方案:遍历所有用户(不推荐)
如果因为权限或其他原因无法使用集合组查询,可以遍历所有用户文档,逐个检查其下的设备序列号。但用户数量较多时,该方法效率极低,且会消耗大量读取配额。
代码示例
const targetSerialNumber = "你要查找的目标序列号"; // 先获取所有用户文档 firestoreDb.collection("users").get() .then(usersSnapshot => { // 用Promise.all并行处理所有用户的设备查询 const checkDevicePromises = usersSnapshot.docs.map(userDoc => { return userDoc.ref.collection("devices").get() .then(devicesSnapshot => { const deviceData = devicesSnapshot.docs[0].data(); if (deviceData["serial number"] === targetSerialNumber) { return userDoc.id; } return null; }); }); return Promise.all(checkDevicePromises); }) .then(results => { // 过滤掉未匹配的结果,获取用户ID const matchedUserId = results.find(id => id !== null); if (matchedUserId) { console.log("匹配的用户文档ID:", matchedUserId); } else { console.log("未找到对应序列号的设备"); } }) .catch(error => { console.error("查询失败:", error); });
关于你之前的for in循环错误
usersReference是Firestore的集合引用对象,不是可遍历的文档数组,直接用for in循环会遍历引用对象的内部属性,而非用户文档。此外,Firestore的文档查询是异步操作,同步循环无法正确处理异步返回的结果,必须用Promise或async/await来处理异步逻辑。
内容的提问来源于stack exchange,提问作者Travis
相关产品推荐
相关产品推荐

