解决Firestore查询前未等待getUserId()返回有效用户ID导致的空白页问题
问题分析与修复方案
你的核心问题出在getUserId()函数的实现上——它看起来是异步函数,但实际上并没有正确等待Firebase Auth的状态结果就返回了,导致await getUserId()拿到的是undefined,后续用这个无效值查询Firestore自然会出错,最终页面因为未处理的异常变成空白。
为什么原来的代码不生效?
onAuthStateChanged是一个基于回调的监听API,它不会直接返回用户ID,而是在Auth状态变化时触发回调。你的getUserId()函数注册完监听后就立刻返回了(此时没有任何返回值,默认是undefined),完全没有等待回调触发拿到用户ID的过程,这就导致await根本起不到等待作用。
修复步骤
1. 重写getUserId(),用Promise包裹Auth状态监听
把回调式的API转换成Promise,这样await才能正确等待结果:
function getUserId() { // 返回Promise,等待Auth状态确定后再resolve/reject return new Promise((resolve, reject) => { // 注册监听后,拿到结果就取消监听,避免内存泄漏 const unsubscribe = getAuth().onAuthStateChanged((user) => { unsubscribe(); if (user) { console.log("1st uid:" + user.uid); resolve(user.uid); } else { console.log("用户未登录"); reject(new Error("用户未登录")); } }); }); }
2. 调整getProfile(),增加错误处理逻辑
现在await getUserId()能正确拿到用户ID了,但还要处理用户未登录、资料不存在的情况,避免程序崩溃:
async function getProfile() { try { const uid = await getUserId(); console.info("2nd uid: " + uid); const docRef = doc(db, "profiles", uid); console.log("got docref"); const docSnap = await getDoc(docRef); if (docSnap.exists()) { const data = docSnap.data(); console.info("successfully got profile: ", data); return data; } else { console.warn("GET PROFILE ERROR: 用户资料不存在"); // 可以返回默认数据或null,根据业务需求调整 return null; } } catch (error) { console.error("获取用户信息失败: ", error); // 这里可以处理未登录场景,比如跳转到登录页 // window.location.href = "/login"; return null; } }
额外提示
- 现在
getProfile()会严格等待用户ID获取完成后再执行Firestore查询,不会再出现用null/undefined查询的问题。 - 页面空白大概率是因为未处理的异常,加上
try/catch后可以捕获错误并给出提示,或者引导用户登录,避免页面无内容。
内容的提问来源于stack exchange,提问作者shihan-dubU
相关产品推荐
相关产品推荐

