React Native Firebase认证状态无法持久化问题求助
问题原因及解决方案
核心问题
Firebase原生SDK确实会自动持久化用户认证状态,但你的代码在App启动时没有主动同步已持久化的用户状态到Redux。Redux初始状态authenticated: false导致导航器直接跳转至登录页面,即便Firebase中已有保存的用户会话。
解决方案步骤
1. 添加用户状态检查的异步Thunk
在authUserSlice中新增一个用于检查当前用户状态的Thunk,主动从Firebase获取已登录的用户:
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'; import auth from '@react-native-firebase/auth'; const initialState = { authenticated: false, isLoading: true, // 新增加载状态,避免初始闪屏 }; // 新增:检查当前认证状态 export const checkAuthStatus = createAsyncThunk('authUser/checkStatus', async () => { return new Promise((resolve) => { // 使用onAuthStateChanged监听用户状态,首次触发即可获取当前用户 const unsubscribe = auth().onAuthStateChanged(user => { resolve(!!user); // 有用户则返回true,否则false unsubscribe(); // 获取到状态后取消监听 }); }); }); const authUserSlice = createSlice({ name: 'authUser', initialState, extraReducers: build => { build .addCase(getAuthUser.fulfilled, (state, action) => { state.authenticated = action.payload; state.isLoading = false; }) .addCase(signOutUser.fulfilled, (state, action) => { state.authenticated = action.payload; state.isLoading = false; }) .addCase(checkAuthStatus.fulfilled, (state, action) => { state.authenticated = action.payload; state.isLoading = false; }); }, }); export default authUserSlice.reducer; // 原有getAuthUser和signOutUser保持不变,补充错误返回值 export const getAuthUser = createAsyncThunk('authUser/get', async data => { const { email, password } = data; try { await auth().signInWithEmailAndPassword(email, password); console.log('user logged in'); return true; } catch (error) { console.log('Error', error); return false; // 捕获错误后返回false,避免状态异常 } }); export const signOutUser = createAsyncThunk('signOut/get', async () => { try { await auth().signOut(); console.log('User signed out!'); return false; } catch (error) { console.log('error', error); return true; // 错误时保持原状态 } });
2. 在App根组件初始化时调用状态检查
找到你的App根组件(通常是App.js),在组件挂载时调用checkAuthStatus:
import { useEffect } from 'react'; import { useDispatch } from 'react-redux'; import AppRouter from './path/to/AppRouter'; import { checkAuthStatus } from './path/to/authUserSlice'; const App = () => { const dispatch = useDispatch(); useEffect(() => { // App启动时检查用户认证状态 dispatch(checkAuthStatus()); }, [dispatch]); return <AppRouter />; }; export default App;
3. 修改导航器处理加载状态
更新AppRouter,在状态加载完成前显示加载界面,避免直接跳转到登录页:
import { NavigationContainer } from '@react-navigation/native'; import AuthNavigator from './AuthNavigator'; import RooteNavigator from './RooteNavigator'; import { useSelector } from 'react-redux'; import { ActivityIndicator, View } from 'react-native'; const AppRouter = () => { const { authenticated, isLoading } = useSelector(state => state.authUser); if (isLoading) { // 加载状态时显示加载指示器 return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <ActivityIndicator size="large" /> </View> ); } return ( <NavigationContainer> {!authenticated ? <AuthNavigator /> : <RooteNavigator />} </NavigationContainer> ); }; export default AppRouter;
关键说明
onAuthStateChanged是Firebase Auth提供的监听方法,会在App启动时立即触发,返回当前已持久化的用户(如果存在)。- 新增的
isLoading状态用于避免App启动时因Redux初始状态为false而短暂显示登录页的闪屏问题。 - 原有的
getAuthUser和signOutUserThunk中添加了错误返回值,确保Redux状态始终有明确的布尔值。
内容的提问来源于stack exchange,提问作者Mohammed Refat
相关产品推荐
相关产品推荐

