如何取数组ID匹配Firestore数据返回JSON到前端并解决空数组问题
问题修复方案
核心错误原因
- 代码中的Firestore查询
get()是异步IO操作,forEach遍历不会等待这些异步任务执行完成,就提前调用了resolve返回了还没被赋值的空数组。 - 额外冗余问题:可调用云函数
onCall本身支持直接返回异步结果,不需要额外手动封装一层new Promise。
修复后代码(优化版,批量查询减少IO次数)
const functions = require("firebase-functions"); const admin = require('firebase-admin'); admin.initializeApp(functions.config().firebase); exports.getPlayerDataFromTokens = functions.https.onCall(async (data, context) => { try { const db = admin.firestore(); const tokens = data.tokens; // 批量查询所有匹配的Token,替代循环单条查询,性能更好 const querySnapshot = await db.collection("Football_Player_Data") .where("Token", "in", tokens) .get(); const playerArray = []; querySnapshot.forEach((doc) => { const docData = doc.data(); playerArray.push({ "Token": docData.Token, "PlayerID": docData.PlayerID, "Jersey_Number": docData.Jersey_Number, "Position": docData.Position, "Team": docData.Team, "Multiplier": docData.Multiplier }); }); // 云函数会自动序列化返回值,不需要手动JSON.stringify return playerArray; } catch (error) { console.log("Error getting documents: ", error); // 按云函数规范抛出错误给前端 throw new functions.https.HttpsError('internal', '查询球员数据失败', error); } });
注意事项
- Firestore的
in查询单次最多支持10个匹配值,如果你的tokens数组长度超过10,需要自行拆分为多个批次查询,再合并结果即可。 - 如果确实需要保留原逻辑单条查询,可改用
Promise.all等待所有异步查询完成再返回,示例逻辑如下:
// 单条查询兼容逻辑(tokens长度不确定时可选) const queryPromises = tokens.map(token => db.collection("Football_Player_Data").where("Token", "==", token).get() ); // 等待所有查询完成 const querySnapshots = await Promise.all(queryPromises); const playerArray = []; querySnapshots.forEach(snapshot => { snapshot.forEach(doc => { // 组装数据逻辑和上面一致 playerArray.push(doc.data()) }) }) return playerArray;
内容的提问来源于stack exchange,提问作者Zzz
相关产品推荐
相关产品推荐

