使用async/await调用Firebase Cloud Firestore查询返回Pending Promise问题
Fixing async/await Firestore Query to Return Document Data Instead of Pending Promise
我瞅了下你的代码,问题出在几个关键地方,咱们一步步把它改对:
核心问题分析
forEach的返回值无法传递到外层:你在querySnapshot.forEach里返回doc.data(),但forEach方法不会把内部的返回值传递出来,相当于这个返回值直接“消失”了,外层的try块最后没有任何返回,所以函数默认返回undefined,async函数会把它包装成一个resolved的Promise,但这显然不是你要的用户数据。- 错误被默默吞掉:你的
catch块只打印了错误日志,但没有重新抛出错误,调用这个函数的地方根本不知道发生了异常,只能拿到一个resolved的Promise。 - 缺少无匹配文档的处理:如果查询没有找到任何文档,你的代码也没有返回明确的结果。
修正后的代码
async getUser(emailAddress) { // Return null if emailAddress is blank if (!emailAddress) { return null; } // Assume @db points to your Cloud Firestore database const query = db.collection('users').where('emailAddress', '==', emailAddress); try { const querySnapshot = await query.get(); // Since you mentioned the query returns only one doc, grab the first one directly if (!querySnapshot.empty) { return querySnapshot.docs[0].data(); } // Return null if no matching document exists return null; } catch(e) { console.log('Error getting user: ', e); // Re-throw the error so the caller can handle it properly throw e; } }
关键改动说明
- 替换
forEach为直接访问docs[0]:因为你明确说查询只返回一个文档,没必要用遍历,直接取第一个文档更高效也更直观。 - 增加
querySnapshot.empty判断:避免当没有匹配文档时,访问docs[0]出现undefined的问题。 - 重新抛出异常:让调用者可以通过
try/catch或者.catch()处理错误,而不是错误被默默忽略。 - 统一返回值逻辑:所有分支都有明确的返回值(空邮箱返回null,找到文档返回数据,没找到返回null,出错抛出错误)。
正确调用方式
调用这个async函数时,记得要用await(在async函数内部)或者.then()来获取结果:
// 用async/await调用 async function loadUser() { try { const user = await getUser('john@example.com'); if (user) { console.log('Got user data:', user); } else { console.log('No user found with that email'); } } catch (error) { console.error('Failed to load user:', error); } } // 或者用Promise链式调用 getUser('jane@example.com') .then(user => { if (user) { console.log('Got user data:', user); } else { console.log('No user found with that email'); } }) .catch(error => console.error('Failed to load user:', error));
内容的提问来源于stack exchange,提问作者Crashalot
相关产品推荐
相关产品推荐

