React中使用Firebase显示当前用户昵称刷新报错的解决方法
问题描述
我尝试在React的Sidebar组件中显示当前用户的昵称,编写了如下代码:
import {auth, dataBase} from '../firebase-config.js'; function Sidebar() { const [firebaseUserInfo, setFirebaseUserInfo] = useState(auth.currentUser); return ( <div className='sidebar-container'> <header> <p>{firebaseUserInfo.displayName}</p> </header> </div> ); }
起初代码可以正常运行,但离开后返回刷新应用时,出现以下错误:
Cannot read properties of null (reading 'displayName') TypeError: Cannot read properties of null (reading 'displayName')
请问如何修复该问题并正常渲染用户昵称?
补充代码
signIn.js 导入及Google认证函数
import React, {useState, useEffect} from 'react'; import {auth, googleProvider, facebookProvider, twitterProvider, githubProvider} from '../firebase-config.js'; import {signInWithPopup, signInWithEmailAndPassword} from 'firebase/auth'; import Cookies from 'universal-cookie'; const signInWithGoogle = async () => { try{ const result = await signInWithPopup(auth, googleProvider); console.log(result); cookies.set("auth-token", result.user.refreshToken); setIsSignIn(true); } catch (err){ console.error(err); } }
firebase-config.js
// Import the functions you need from the SDKs you need import { initializeApp } from "firebase/app"; import { getAnalytics } from "firebase/analytics"; import {getAuth, GoogleAuthProvider, createUserWithEmailAndPassword, FacebookAuthProvider, TwitterAuthProvider, GithubAuthProvider} from 'firebase/auth'; import {getFirestore} from 'firebase/firestore'; // TODO: Add SDKs for Firebase products that you want to use // https://firebase.google.com/docs/web/setup#available-libraries // Your web app's Firebase configuration // For Firebase JS SDK v7.20.0 and later, measurementId is optional const firebaseConfig = { apiKey: "AIzaSyCtiHPj2f0IB389CHZSkc0cAOCBkYf7RFw", authDomain: "my-chat-app-5b0ae.firebaseapp.com", projectId: "my-chat-app-5b0ae", storageBucket: "my-chat-app-5b0ae.appspot.com", messagingSenderId: "837847743265", appId: "1:837847743265:web:cc6c4987efbf7fe47b5c60", measurementId: "G-CXEMWS349E" }; // Initialize Firebase const app = initializeApp(firebaseConfig); const analytics = getAnalytics(app); export const auth = getAuth(app) export const googleProvider = new GoogleAuthProvider(); export const facebookProvider = new FacebookAuthProvider(); export const twitterProvider = new TwitterAuthProvider(); export const githubProvider = new GithubAuthProvider(); export const dataBase = getFirestore(app)
问题原因
刷新页面时,Firebase Auth尚未完成初始化流程,auth.currentUser会返回null,此时直接访问displayName就会触发空值报错。另外,初始状态仅在组件挂载时设置一次,后续用户登录状态变化时无法自动更新。
修复方案
方案1:添加空值保护(快速临时修复)
在访问displayName时使用可选链操作符,同时设置默认值避免空内容:
<p>{firebaseUserInfo?.displayName || 'Guest'}</p>
方案2:监听Firebase用户状态变化(推荐)
使用useEffect监听Firebase的用户认证状态,实时更新组件内的用户信息:
import { auth, dataBase } from '../firebase-config.js'; import { useState, useEffect } from 'react'; function Sidebar() { const [firebaseUserInfo, setFirebaseUserInfo] = useState(null); useEffect(() => { // 监听用户登录/登出状态变化 const unsubscribe = auth.onAuthStateChanged(user => { setFirebaseUserInfo(user); }); // 组件卸载时取消监听,防止内存泄漏 return () => unsubscribe(); }, []); // 未获取到用户信息时显示加载状态 if (!firebaseUserInfo) { return <div className='sidebar-container'><header><p>Loading...</p></header></div>; } return ( <div className='sidebar-container'> <header> <p>{firebaseUserInfo.displayName || 'Guest'}</p> </header> </div> ); }
方案3:结合Cookie重新认证
由于你使用Cookie存储了刷新令牌,可以在组件初始化时尝试通过Cookie恢复用户状态:
import { auth, dataBase } from '../firebase-config.js'; import { useState, useEffect } from 'react'; import Cookies from 'universal-cookie'; const cookies = new Cookies(); function Sidebar() { const [firebaseUserInfo, setFirebaseUserInfo] = useState(null); useEffect(() => { const token = cookies.get("auth-token"); if (token) { // 使用刷新令牌重新登录 auth.signInWithRefreshToken(token) .then(userCredential => { setFirebaseUserInfo(userCredential.user); }) .catch(err => { console.error(err); cookies.remove("auth-token"); }); } // 同时监听状态变化 const unsubscribe = auth.onAuthStateChanged(user => { setFirebaseUserInfo(user); }); return () => unsubscribe(); }, []); if (!firebaseUserInfo) { return <div className='sidebar-container'><header><p>Loading...</p></header></div>; } return ( <div className='sidebar-container'> <header> <p>{firebaseUserInfo.displayName || 'Guest'}</p> </header> </div> ); }
关键说明
onAuthStateChanged是Firebase Auth的核心状态监听方法,会在用户登录、登出或凭证过期时自动触发,确保组件能实时获取最新用户数据。- 可选链操作符
?.是ES2020语法,能安全访问嵌套属性,避免空值类型错误。 - 必须在组件卸载时取消状态监听(调用
unsubscribe),防止内存泄漏问题。
内容的提问来源于stack exchange,提问作者Randy Steward
相关产品推荐
相关产品推荐

