Firebase Auth currentUser始终为null,SvelteKit路由刷新后被踢
解决方案:SvelteKit路由保护中Firebase认证状态同步问题
核心问题是SvelteKit的load函数默认在服务端执行时,Firebase的onAuthStateChanged还未完成客户端的认证状态同步,导致直接读取authUser store得到null,触发不必要的登录跳转。以下是针对性修复方案:
1. 异步等待认证状态初始化(推荐)
在authStore中封装异步函数,确保load函数能等到Firebase完成认证状态同步后再判断:
修改src/lib/authStore.ts:
import { writable } from 'svelte/store'; import { onAuthStateChanged } from 'firebase/auth'; import { auth } from './firebase'; type AuthUser = { uid: string; email: string | null; } | null; export const authUser = writable<AuthUser>(null); // 新增:异步获取认证用户,等待首次状态同步 export const getAuthUser = async (): Promise<AuthUser> => { // 先检查store已有值 const currentUser = authUser.subscribe(val => val)(); if (currentUser !== null) return currentUser; // 等待Firebase返回认证状态 return new Promise(resolve => { const unsubscribe = onAuthStateChanged(auth, (user) => { const mappedUser: AuthUser = user ? { uid: user.uid, email: user.email } : null; authUser.set(mappedUser); resolve(mappedUser); unsubscribe(); // 获取结果后取消监听 }); }); };
更新受保护路由的src/routes/protected/+page.ts:
import { redirect } from "@sveltejs/kit"; import { getAuthUser } from '$lib/authStore'; export const load = async () => { const user = await getAuthUser(); if (!user) { throw redirect(302, '/login'); } return { user }; };
2. 禁用该路由的SSR(快速临时方案)
如果受保护页面不需要服务端渲染,可以直接关闭SSR,确保代码在客户端执行时Firebase已完成状态同步:
// src/routes/protected/+page.ts export const ssr = false; export const load = async () => { const { getAuthUser } = await import('$lib/authStore'); const user = await getAuthUser(); if (!user) throw redirect(302, '/login'); return { user }; };
3. 清理登录页冗余代码
登录页中重复的onAuthStateChanged监听是多余的,authStore已全局处理状态同步,直接跳转即可:
<!-- src/routes/login/+page.svelte --> <script lang="ts"> import { goto } from '$app/navigation'; import { signInWithEmailAndPassword} from 'firebase/auth'; import { auth } from "$lib/firebase"; let email: string = ''; let password: string = ''; const login = () => { signInWithEmailAndPassword(auth, email, password) .then(() => goto('/protected')) .catch((error) => console.log(error.code, error.message)); }; </script>
4. 显式配置Firebase持久化
确保Firebase认证状态在页面刷新后保留,在src/lib/firebase.ts中添加持久化配置:
import { initializeApp, getApps} from "firebase/app"; import { getAuth, setPersistence, browserLocalPersistence } from "firebase/auth"; const firebaseConfig = { apiKey: "", authDomain: "", projectId: "", storageBucket: "", messagingSenderId: "", appId: "", measurementId: "" }; const app = getApps().length === 0 ? initializeApp(firebaseConfig) : getApps()[0]; export const auth = getAuth(app); // 强制设置本地持久化 setPersistence(auth, browserLocalPersistence) .catch(err => console.error('持久化配置失败:', err));
内容的提问来源于stack exchange,提问作者Alex
相关产品推荐
相关产品推荐

