NextJS集成Firebase项目中访问Firestore用户patient字段时出现TypeError: Cannot read property 'uid' of null的问题解决
修复Firestore访问时的
Cannot read property 'uid' of null错误 嘿,我来帮你搞定这个问题!你遇到的Cannot read property 'uid' of null错误,主要是两个小细节没处理好,咱们一步步来修复:
问题根源
- 错误的用户状态获取方式:你在
random.js里直接用getAuth()来获取user,但这个方法只是返回Auth实例,不是你在AuthProvider上下文里维护的user状态。你已经封装了useAuth钩子,应该用它来获取用户信息。 - 未处理异步加载状态:用户认证状态是异步加载的,组件初始化时
user会是null,这时候直接访问user.uid就会触发报错。
修复步骤
1. 改用useAuth获取用户状态
把random.js里的const {user} = getAuth();替换成const { user } = useAuth();,这样才能拿到AuthProvider里维护的用户状态。
2. 用useEffect处理异步订阅
把Firestore的订阅逻辑放到useEffect里,并且只有当user存在时才执行订阅,同时记得清理订阅防止内存泄漏。
修改后的random.js代码
import { doc, onSnapshot, getFirestore } from 'firebase/firestore' import { useAuth } from '../auth' import { useState, useEffect } from 'react' import Link from 'next/link' export default function Random (){ const db = getFirestore(); const { user } = useAuth(); // 使用自定义的useAuth钩子获取用户状态 const [patientName, setPatientName] = useState(''); // 存储患者姓名的状态 useEffect(() => { let unsub; // 仅当user存在时,才订阅Firestore文档 if (user) { unsub = onSnapshot(doc(db, "Users", user.uid), (doc) => { if (doc.exists()) { console.log("Current data: ", doc.data()); setPatientName(doc.data().patient); // 更新患者姓名到状态中 } else { console.log("No such document!"); } }); } // 组件卸载时清理订阅,避免内存泄漏 return () => { if (unsub) unsub(); }; }, [user]); // 依赖user,当用户状态变化时重新执行订阅 return ( <div> { user ? `Patient: ${patientName}` : `No patient` } </div> ) }
额外优化建议
你可以在返回的JSX里添加加载状态提示,提升用户体验——因为用户状态是异步加载的,初始阶段user会处于未定义状态:
return ( <div> { user ? `Patient: ${patientName}` : user === null ? `No patient` : `Loading...` } </div> )
内容的提问来源于stack exchange,提问作者mukunda
相关产品推荐
相关产品推荐

