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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 06:15:11