Firebase升级至10.0.0后NextJS中Current User状态无法保持求助
Firebase v10升级后NextJS登录用户状态丢失问题解决
核心问题分析
升级Firebase到10.0.0后,onAuthStateChanged未能正确监听用户状态变化,加上NextJS的SSR特性导致Auth状态无法在客户端持久化,最终出现登录后current user返回undefined的情况。
解决方案
1. 确保Auth在客户端初始化(避免SSR干扰)
NextJS的服务端渲染环境没有浏览器本地存储,全局初始化Auth会导致状态无法持久化。修改AuthContext.js,将Auth实例放到组件内部用useMemo初始化:
import React from "react"; import { onAuthStateChanged, getAuth, setPersistence, browserLocalPersistence } from "firebase/auth"; import firebase_app from "@/firebase/config"; export const AuthContext = React.createContext({}); export const useAuthContext = () => React.useContext(AuthContext); export const AuthContextProvider = ({ children }) => { const [user, setUser] = React.useState(null); const [loading, setLoading] = React.useState(true); // 用useMemo确保Auth实例只在客户端创建一次 const auth = React.useMemo(() => getAuth(firebase_app), []); React.useEffect(() => { const initAuth = async () => { // 手动设置本地持久化,确保状态保存 await setPersistence(auth, browserLocalPersistence); const unsubscribe = onAuthStateChanged(auth, (authUser) => { setUser(authUser); setLoading(false); }); return unsubscribe; }; initAuth(); }, [auth]); return ( <AuthContext.Provider value={{ user }}> {loading ? <div>Loading...</div> : children} </AuthContext.Provider> ); };
2. 页面组件必须是客户端组件
所有需要访问AuthContext的页面/组件,必须添加'use client'指令,确保在客户端执行:
// /app/blog/page.js 'use client'; import { useAuthContext } from "@/contexts/AuthContext"; export default function BlogPage() { const { user } = useAuthContext(); return ( <div> {user ? <p>当前用户:{user.email}</p> : <p>未登录</p>} </div> ); }
3. 修正登录逻辑中的状态异步问题
登录后立刻打印user会拿到旧值(React状态更新是异步的),无需在handleSignIn中依赖user状态,直接通过onAuthStateChanged的回调自动更新上下文:
// Login.js 'use client'; import { useAuthContext } from "@/contexts/AuthContext"; import { signIn } from "@/utils/auth"; import { useRouter } from "next/navigation"; import { useState } from "react"; export default function LoginPage() { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [errorStop, setErrorStop] = useState(''); const router = useRouter(); async function handleSignIn() { if (password && email) { const { result, error } = await signIn(email, password); if (error) { setErrorStop(error); } else { // 无需等待user更新,跳转后AuthContext会自动获取最新状态 router.push("/blog"); } } } return ( <div> <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} /> <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} /> <button onClick={handleSignIn}>登录</button> {errorStop && <p>{errorStop}</p>} </div> ); }
4. 检查Firebase初始化配置
确保firebase/config.js的初始化代码正确,没有重复初始化:
// firebase/config.js import { initializeApp } from "firebase/app"; const firebaseConfig = { // 你的配置信息 }; // 确保只初始化一次 const firebase_app = initializeApp(firebaseConfig); export default firebase_app;
内容的提问来源于stack exchange,提问作者humam choudhary
相关产品推荐
相关产品推荐

