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

Vercel部署后Firebase Google Auth登出后currentUser始终为null

问题:Vercel部署后Google Auth仅首次正常工作,登出后currentUser始终为null

本地localhost环境下可多次重新登录,currentUser始终返回包含数据的对象,但部署到Vercel后,Google Auth仅首次登录正常,登出后再次登录时currentUser始终为null。

已尝试的解决方法

  • 调整useEffect的依赖项
  • 禁用Chrome的chrome://flags/#third-party-storage-partitioning设置

相关代码

'use client'
import { useEffect, useState, useContext, createContext } from 'react'
import { useRouter } from 'next/navigation'
import {getAuth, GoogleAuthProvider, onAuthStateChanged, signInWithRedirect} from 'firebase/auth'
import { User } from 'firebase/auth'
import '@/services/firebaseConfig'
import { DocumentData, doc, getDoc } from 'firebase/firestore'
import {auth, db} from '@/services/firebaseConfig'
import { usePathname } from 'next/navigation'
import {DEFAULT_REDIRECT_PATH} from "@/config/constants";

interface AuthProviderProps {
  children: React.ReactNode
}

interface AuthContextType {
  user: User | null
  authLoading: boolean
  userData: DocumentData | undefined
  setUser: (user: User | null) => void
  setUserData: (user: DocumentData | undefined) => void
}

const AuthContext = createContext<AuthContextType | null>(null)

export const useAuth = () => {
  return useContext(AuthContext)
}

export const AuthProvider = ({ children }: AuthProviderProps) => {
  const router = useRouter()
  const [authLoading, setAuthLoading] = useState(false)
  const [user, setUser] = useState<User | null>(null)
  const [userData, setUserData] = useState<DocumentData | undefined>()
  const pathname = usePathname()

  useEffect(() => {
    const auth = getAuth()
    const unsubscribe = onAuthStateChanged(auth,  (currentUser) => {
      if (currentUser) {
        const userRef = doc(db, 'users', currentUser.uid)
        // const userDoc = await getDoc(userRef)
        // setUser(currentUser)
        // setUserData(userDoc.data())
        if (['/login', '/register'].includes(pathname || '')) {
          if(currentUser.emailVerified) {
            router.replace(DEFAULT_REDIRECT_PATH)
          }
        }
      }
      else {
        // setUser(null)
        // setUserData(undefined)

      }
      console.log('currentUser', currentUser)

      if (
        !currentUser &&
        !['/', '/register', '/legal', '/login'].includes(pathname || '')
      ) {
        router.replace('/login')
      } else {
        // setAuthLoading(false)
      }
    })

    return () => unsubscribe()
  }, [user])

  return (
    <AuthContext.Provider value={{ user, authLoading, userData, setUser, setUserData }}>
      {children}
    </AuthContext.Provider>
  )
}

问题分析与解决建议

  1. 修正useEffect依赖项:当前useEffect依赖user状态,但回调内未更新user(相关代码被注释),导致监听逻辑异常。应将依赖项改为pathname和router,或使用空数组(因为onAuthStateChanged是长期监听,无需频繁重新订阅)。
  2. 同步Context中的用户状态:取消注释回调里的setUser(currentUser)和setUserData代码,确保Firebase认证状态变化时,Context中的user状态能同步更新,否则UI层无法获取最新认证信息。
  3. 检查Firebase跨域配置:在Firebase控制台中确认:
    • 认证 > 设置 > 授权域已添加Vercel部署的域名
    • firebaseConfig中的authDomain与部署域名完全匹配
  4. 处理Next.js客户端缓存:作为客户端组件,可能存在缓存导致认证状态未刷新。可在相关页面添加export const dynamic = 'force-dynamic'强制禁用静态缓存,或在登录/登出操作后调用revalidatePath刷新路由。
  5. 修复异步用户数据获取:若需从Firestore获取用户数据,需将回调改为async函数,正确处理异步逻辑,示例调整如下:
useEffect(() => {
  const auth = getAuth()
  const unsubscribe = onAuthStateChanged(auth, async (currentUser) => {
    if (currentUser) {
      setUser(currentUser)
      const userRef = doc(db, 'users', currentUser.uid)
      const userDoc = await getDoc(userRef)
      setUserData(userDoc.data())
      if (['/login', '/register'].includes(pathname || '')) {
        if(currentUser.emailVerified) {
          router.replace(DEFAULT_REDIRECT_PATH)
        }
      }
    } else {
      setUser(null)
      setUserData(undefined)
    }
    console.log('currentUser', currentUser)

    if (
      !currentUser &&
      !['/', '/register', '/legal', '/login'].includes(pathname || '')
    ) {
      router.replace('/login')
    }
  })

  return () => unsubscribe()
}, [pathname, router])

内容的提问来源于stack exchange,提问作者Александр Мерный

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 16:27:25