Firestore数据存在但Promise返回空值的问题排查
问题排查与解决方案
核心问题分析
输出Tokens,,,,,说明每个用户ID对应的查询要么未找到文档,要么文档中没有有效的deviceToken字段,最终返回的是包含多个空/undefined元素的数组。
排查步骤
1. 确认查询是否命中文档
在异步map函数内添加日志,查看每个ID的查询结果数量:
async function getTokensForUsers(ids) { const promises = ids.map(async (id) => { console.log("Querying for user with id: " + id); const querySnapshot = await db.collection('users').where('deviceUid', '==', id).get(); // 新增日志:查看命中的文档数 console.log(`ID ${id} matched ${querySnapshot.size} documents`); return querySnapshot.docs.map(doc => doc.data().deviceToken); }); let tokens = await Promise.all(promises); return tokens.flat(); }
如果日志显示matched 0 documents,说明查询条件不匹配。
2. 验证字段名与数据类型一致性
- 字段名大小写: Firestore字段名区分大小写,确认集合中文档的字段是
deviceUid(而非DeviceUid或其他变体)。 - 数据类型匹配: 若Firestore中
deviceUid存储为数字,而传入的ids是字符串类型,查询会无结果。需统一类型,例如将ID转为数字:where('deviceUid', '==', Number(id))。 - 清理无效ID: 检查
ids数组中是否存在空字符串、null或undefined值,这类值会导致无效查询。
3. 检查Firestore安全规则
确保应用拥有读取users集合的权限。若规则限制仅认证用户可读取,需确认代码运行时已完成用户认证流程。
4. 确认文档包含deviceToken字段
即使查询命中文档,若文档中未设置deviceToken,会返回undefined。添加日志查看文档具体数据:
return querySnapshot.docs.map(doc => { const docData = doc.data(); console.log(`Document data for ID ${id}:`, docData); return docData.deviceToken; });
优化后的代码
添加错误处理和无效值过滤,提升稳定性:
async function getTokensForUsers(ids) { try { const tokenPromises = ids.map(async (userId) => { if (!userId) { console.warn("Skipping empty user ID"); return []; } const querySnapshot = await db.collection('users') .where('deviceUid', '==', userId) .get(); if (querySnapshot.empty) { console.warn(`No user found with deviceUid: ${userId}`); return []; } // 过滤掉无deviceToken的文档 return querySnapshot.docs .map(doc => doc.data().deviceToken) .filter(token => typeof token === 'string' && token.length > 0); }); const tokenArrays = await Promise.all(tokenPromises); return tokenArrays.flat(); } catch (error) { console.error("Failed to fetch device tokens:", error); throw error; } }
内容的提问来源于stack exchange,提问作者HarryMoy
相关产品推荐
相关产品推荐

