You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 19:35:56