如何访问Firestore中Promise返回的secondSnapshot.data()对应值
问题原因
- 内层
map的回调函数没有显式返回值:你没有给comment.get()语句加return,所以map遍历出来的每一项默认都是undefined,这是你打印address得到undefined的直接原因。就算你补上return,此时address也只会是装满Promise实例的数组,不是你期望的实际数据——then回调的执行时机晚于当前同步代码,你打印address的时候,Firebase的异步查询还没完成,secondSnapshot.data()的结果还没返回。 - 你没有等待所有子评论的异步查询完成,就直接构造了
posts对象执行setComments,所以最终存储的评论数据里comments字段永远是空数组。
修复后的代码示例
useEffect(() => { const unsubscribe = firestore.collection(`comments`).onSnapshot(async (snapshot) => { // 生成所有帖子的处理Promise,后续统一等待完成 const postPromises = snapshot.docs.map(async (doc) => { const docData = doc.data(); // 并行处理所有子评论的异步查询,等待全部返回结果 const comments = docData.comments ? await Promise.all( docData.comments.map(async (comment) => { const secondSnapshot = await comment.get(); return secondSnapshot.data(); }) ) : []; return { username: docData.username, date: docData.date.seconds, text: docData.text, votes: docData.votes, comments: comments }; }); // 等待所有帖子的处理逻辑完成后再更新状态 const posts = await Promise.all(postPromises); props.setComments(posts); }); // 组件卸载时取消快照监听,避免内存泄漏 return () => unsubscribe(); }, [location]);
修复说明
- 给
onSnapshot的回调加上async标记,内部用await等待异步操作完成 - 所有并行的Firebase查询用
Promise.all包裹,统一等待全部查询完成后再构造最终数据 - 返回
unsubscribe函数,组件卸载时主动取消Firestore的快照监听
内容的提问来源于stack exchange,提问作者John Ko
相关产品推荐
相关产品推荐

