如何在React应用中通过Firebase Auth更新用户状态
问题修复方案
一、Google登录无反应+状态不更新的问题
1. 给Google登录按钮绑定点击事件
你的Google登录按钮只是空标签,未触发登录逻辑,修改为绑定signInWithGoogle函数:
// 替换原Google登录的<a>标签 <button className='btn btn-flex flex-center btn-light btn-lg w-100 mb-5' onClick={async () => { setLoading(true); try { await signInWithGoogle(); setLoading(false); navigate('/dashboard'); } catch (err) { console.error(err); setLoading(false); } }} disabled={loading} > <img alt='Logo' src={toAbsoluteUrl('/media/svg/brand-logos/google-icon.svg')} className='h-20px me-3' /> Continue with Google </button>
2. 监听Firebase Auth状态变化,同步React用户状态
你引入了useAuth但未利用它同步登录状态,在Auth上下文文件中添加状态监听:
// 在你的Auth.js文件中修改AuthProvider import { useEffect, useState, createContext, useContext } from 'react'; import { auth } from '../../firebase.js'; import { onAuthStateChanged } from 'firebase/auth'; const AuthContext = createContext(); export function AuthProvider({ children }) { const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); useEffect(() => { // 监听用户登录/登出状态变化 const unsubscribe = onAuthStateChanged(auth, (currentUser) => { setUser(currentUser); setLoading(false); }); // 组件卸载时取消监听 return unsubscribe; }, []); return ( <AuthContext.Provider value={{ user, loading }}> {!loading && children} </AuthContext.Provider> ); } export function useAuth() { return useContext(AuthContext); }
3. 在Login组件中利用useAuth同步状态
修改Login组件,添加状态监听,确保登录后自动同步:
export function Login() { const [loading, setLoading] = useState(false); const navigate = useNavigate(); const { user } = useAuth(); // 获取Auth上下文的用户状态 // 如果用户已登录,自动跳转到 dashboard useEffect(() => { if (user) { navigate('/dashboard'); } }, [user, navigate]); // ... 原formik逻辑保持不变 }
这样不管是邮箱登录还是Google登录,只要Firebase认证成功,onAuthStateChanged就会触发,自动更新React的用户状态。
二、关于Firebase Token与Cookie的问题
Firebase Auth默认不会把Token存在Cookie里,它会将用户的ID Token、Refresh Token存储在浏览器的localStorage/IndexedDB中,自动管理Token的刷新。
如果你的业务需要将Token存在Cookie(比如和后端API交互时),可以手动获取并设置:
import { getAuth, getIdToken, onIdTokenChanged } from 'firebase/auth'; // 在AuthProvider或需要的组件中添加 useEffect(() => { const unsubscribe = onIdTokenChanged(auth, (user) => { if (user) { // 获取最新的ID Token getIdToken(user).then(idToken => { // 设置Cookie,可根据需求调整参数 document.cookie = `authToken=${idToken}; path=/; secure; SameSite=Strict`; }); } else { // 用户登出时清除Cookie document.cookie = 'authToken=; path=/; expires=Thu, 01 Jan 1970 00:00:00 UTC'; } }); return unsubscribe; }, []);
内容的提问来源于stack exchange,提问作者Ben Ille
相关产品推荐
相关产品推荐

