Firebase Google重定向登录失败(弹窗登录正常)问题求助
Firebase Google重定向登录失败(弹窗登录正常)问题求助
大家好,我正在给我的Next.js Web应用集成Firebase认证,支持邮箱密码和Google登录两种方式。之前用Google弹窗登录(signInWithPopup)一切正常,但最近想改成**重定向登录(signInWithRedirect)**后,就遇到了问题,登录流程走不通,想请大家帮忙排查下问题~
下面是我的项目环境和核心代码:
环境版本
package.json中的Firebase依赖:
"firebase": "^11.10.0"
认证上下文核心代码(AuthContext.tsx)
'use client'; import { createContext, useEffect, useState, ReactNode, useContext } from 'react'; import { auth, provider } from '@/lib/firebase'; import { signOut, onAuthStateChanged, User, signInWithRedirect, signInWithEmailAndPassword, createUserWithEmailAndPassword, getRedirectResult, getIdToken, signInWithPopup, } from 'firebase/auth'; import { toast } from '@/hooks/use-toast'; import { doc, getDoc, setDoc } from 'firebase/firestore'; import { db } from '@/lib/firebase'; interface AuthContextType { user: User | null; loading: boolean; login: () => Promise<void>; loginWithredirect: () => Promise<void>; loginWithEmailPwd: (email: string, password: string) => Promise<void>; signUpWithEmailPwd: (email: string, password: string) => Promise<void>; sendWelcomeEmail: (user: User) => Promise<void>; logout: () => Promise<void>; } const AuthContext = createContext<AuthContextType>({ user: null, loading: true, login: async () => {}, loginWithredirect: async () => {}, loginWithEmailPwd: async () => {}, signUpWithEmailPwd: async () => {}, sendWelcomeEmail: async () => {}, logout: async () => {}, }); export function useAuth() { return useContext(AuthContext); } export function AuthProvider({ children }: { children: ReactNode }) { const [user, setUser] = useState<User | null>(null); const [loading, setLoading] = useState(true); useEffect(() => { console.log('loaded'); getRedirectResult(auth) .then(async (result) => { console.log(result); if (result?.user) { console.log(result.user); await setToken(result.user); await saveUserToFirestore(result.user); setUser(result.user); } }) .catch(() => { // Ignore errors, onAuthStateChanged will handle fallback }); const unsubscribe = onAuthStateChanged(auth, (user) => { setUser(user); setLoading(false); }); return () => unsubscribe(); }, []); // Google重定向登录 const loginWithredirect = async () => { setLoading(true); try { await signInWithRedirect(auth, provider); // 原代码这里判断auth.currentUser是无效的,因为重定向后当前函数会终止,不会执行到这里 if (auth.currentUser) { await setToken(auth.currentUser); await saveUserToFirestore(auth.currentUser); } } catch (e) { throw new Error('Login Failed! Try Again'); } finally { setLoading(false); } }; // Google弹窗登录(正常工作) const login = async () => { setLoading(true); try { const result = await signInWithPopup(auth, provider); if (result.user) { await setToken(result.user); await saveUserToFirestore(result.user); setUser(result.user); } } catch (e) { throw new Error('Login Failed! Try Again'); } finally { setLoading(false); } }; const setToken = async (user: User) => { const token = await getIdToken(user); document.cookie = `auth=${token}; path=/;`; }; // 保存用户到Firestore const saveUserToFirestore = async (user: User) => { if (!user?.uid) return; const userRef = doc(db, 'users', user.uid); const snap = await getDoc(userRef); if (!snap.exists()) { try { console.log('trying brevo api...'); sendWelcomeEmail(user); toast({ title: 'Welcome email sent!', description: 'You have been added to our mailing list.', }); await setDoc(userRef, { uid: user.uid, displayName: user.displayName || '', email: user.email || '', photoURL: user.photoURL || '', provider: user.providerData?.[0]?.providerId || 'google', createdAt: new Date(), welcomeEmailSent: true, }); } catch (error) { toast({ title: 'Failed to send welcome email', description: 'There was an error adding you to our mailing list.', variant: 'destructive', }); await setDoc(userRef, { uid: user.uid, displayName: user.displayName || '', email: user.email || '', photoURL: user.photoURL || '', provider: user.providerData?.[0]?.providerId || 'google', createdAt: new Date(), welcomeEmailSent: false, }); } } else { // 可选:更新用户元数据 await setDoc( userRef, { displayName: user.displayName || '', email: user.email || '', photoURL: user.photoURL || '', provider: user.providerData?.[0]?.providerId || 'google', lastLogin: new Date(), }, { merge: true } ); } }; // 邮箱密码登录 const loginWithEmailPwd = async (email: string, password: string) => { setLoading(true); try { if (email && password) { await signInWithEmailAndPassword(auth, email, password); } } finally { setLoading(false); } }; // 邮箱密码注册 const signUpWithEmailPwd = async (email: string, password: string) => { setLoading(true); try { await createUserWithEmailAndPassword(auth, email, password); if (auth.currentUser) { await setToken(auth.currentUser); await saveUserToFirestore(auth.currentUser); } } finally { setLoading(false); // 原代码此处为setLoading(fals,已修正笔误) } }; // 发送欢迎邮件(原代码未实现具体逻辑) const sendWelcomeEmail = async (user: User) => { // 此处应为调用Brevo API的逻辑 }; // 退出登录 const logout = async () => { setLoading(true); try { await signOut(auth); document.cookie = 'auth=; path=/; expires=Thu, 01 Jan 1970 00:00:00 UTC;'; } catch (e) { throw new Error('Logout Failed! Try Again'); } finally { setLoading(false); } }; return ( <AuthContext.Provider value={{ user, loading, login, loginWithredirect, loginWithEmailPwd, signUpWithEmailPwd, sendWelcomeEmail, logout, }} > {!loading && children} </AuthContext.Provider> ); }
具体问题现象
点击调用loginWithredirect后,页面正常跳转到Google登录页面,登录完成后也能跳回应用,但:
- 用户状态没有更新,页面依然显示未登录状态
getRedirectResult返回的result始终是null- 原本应该执行的
saveUserToFirestore逻辑完全没触发
而弹窗登录的login函数完全正常,能正确获取用户信息、保存到Firestore并更新用户状态。
麻烦大家帮忙看看我的重定向登录逻辑哪里出了问题,或者有没有Firebase控制台的配置我漏掉了?
内容来源于stack exchange
相关产品推荐
相关产品推荐

