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

React Native+Firebase双角色登录失败及角色导航跳转求助

问题解决方案

一、修复登录失败问题

你的登录代码存在两个关键问题:

  1. 未定义email和password状态:handleSignIn里用到的账号密码变量没有在组件内声明状态,无法获取用户输入内容。
  2. 缺少Firebase基础配置验证:需确认已在项目中正确初始化Firebase,且控制台「Authentication」模块已启用「邮箱/密码」登录方式。

修改后的SignIn组件代码:

import { useState } from 'react';
import { View, TextInput, Button, Alert } from 'react-native';
import { auth, db } from '../firebase/config'; // 替换为你的Firebase配置路径

const SignIn = ({ navigation }) => {
  // 新增账号密码状态管理
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [user, setUser] = useState(null);

  const handleSignIn = async () => {
    try {
      // 校验输入合法性
      if (!email || !password) {
        Alert.alert('提示', '请输入完整的邮箱和密码');
        return;
      }
      // 执行Firebase登录
      const userCredentials = await auth.signInWithEmailAndPassword(email, password);
      const user = userCredentials.user;
      console.log('登录成功:', user.email);

      // 获取用户角色并跳转对应页面
      const userDoc = await db.collection('users').doc(user.uid).get();
      const userData = userDoc.data();
      setUser(userData);

      // 根据角色跳转至专属导航首页
      if (userData?.role === 'admin') {
        navigation.replace('AdminNavi');
      } else {
        navigation.replace('UserNavi');
      }
    } catch (error) {
      // 更明确的错误提示,便于排查问题
      Alert.alert('登录失败', error.message);
      console.error('登录错误详情:', error.code, error.message);
    }
  };

  return (
    <View style={{ padding: 20, gap: 15 }}>
      <TextInput
        placeholder="邮箱"
        value={email}
        onChangeText={setEmail}
        keyboardType="email-address"
        autoCapitalize="none"
      />
      <TextInput
        placeholder="密码"
        value={password}
        onChangeText={setPassword}
        secureTextEntry
      />
      <Button title="登录" onPress={handleSignIn} />
    </View>
  );
};

export default SignIn;

二、配置角色自动跳转导航

之前的导航逻辑错误,不能在useEffect中直接渲染导航组件,需在App.js中统一管理用户状态和导航渲染,同时调整AdminNavi和UserNavi的结构,移除已登录状态下不需要的Auth页面。

1. 调整导航组件(移除Auth页面)

修改AdminNavi:

import { DrawerNavigator } from '@react-navigation/drawer';
import AdminTabs from './AdminTabs';
import StackNavigator from './StackNavigator';
import DrawerContent from './DrawerContent';

const Drawer = DrawerNavigator;

const AdminNavi = () => {
  return (
    <Drawer.Navigator
      screenOptions={{ headerShown: false }}
      drawerContent={(props) => <DrawerContent {...props} />}
    >
      {/* 已登录用户无需访问登录页面,移除Auth */}
      <Drawer.Screen name="AdminTabs" component={AdminTabs} />
      <Drawer.Screen name="Stack" component={StackNavigator} />
    </Drawer.Navigator>
  );
};

export default AdminNavi;

修改UserNavi:

import { DrawerNavigator } from '@react-navigation/drawer';
import Tabs from './Tabs';
import StackNavigator from './StackNavigator';
import DrawerContent from './DrawerContent';

const Drawer = DrawerNavigator;

const UserNavi = () => {
  return (
    <Drawer.Navigator
      screenOptions={{ headerShown: false }}
      drawerContent={(props) => <DrawerContent {...props} />}
    >
      {/* 已登录用户无需访问登录页面,移除Auth */}
      <Drawer.Screen name="Tabs" component={Tabs} />
      <Drawer.Screen name="Stack" component={StackNavigator} />
    </Drawer.Navigator>
  );
};

export default UserNavi;

2. 重构App.js,实现全局状态监听和导航切换

import { useState, useEffect } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { auth, db } from './firebase/config'; // 替换为你的Firebase配置路径
import SignIn from './screens/SignIn';
import AdminNavi from './navigators/AdminNavi';
import UserNavi from './navigators/UserNavi';

const Stack = createStackNavigator();

const App = () => {
  const [currentUser, setCurrentUser] = useState(null);
  const [userRole, setUserRole] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    // 监听Firebase用户登录状态变化
    const unsubscribe = auth.onAuthStateChanged(async (user) => {
      setLoading(true);
      if (user) {
        // 从Firestore获取用户角色数据
        const userDoc = await db.collection('users').doc(user.uid).get();
        const data = userDoc.data();
        setCurrentUser(user);
        setUserRole(data?.role);
      } else {
        setCurrentUser(null);
        setUserRole(null);
      }
      setLoading(false);
    });

    // 组件卸载时清理监听
    return () => unsubscribe();
  }, []);

  // 加载状态处理(可替换为自定义加载组件)
  if (loading) {
    return null;
  }

  return (
    <NavigationContainer>
      <Stack.Navigator screenOptions={{ headerShown: false }}>
        {!currentUser ? (
          // 未登录时显示登录页面
          <Stack.Screen name="SignIn" component={SignIn} />
        ) : userRole === 'admin' ? (
          // 管理员登录后显示专属导航
          <Stack.Screen name="AdminNavi" component={AdminNavi} />
        ) : (
          // 普通用户登录后显示专属导航
          <Stack.Screen name="UserNavi" component={UserNavi} />
        )}
      </Stack.Navigator>
    </NavigationContainer>
  );
};

export default App;

额外注意事项

  • 确保Firestore的users集合中,每个用户文档都包含role字段(值为admin或client),否则无法正确判断角色。
  • 如需添加登出功能,在导航的DrawerContent中添加登出按钮,调用auth.signOut()即可触发状态监听,自动返回登录页面。

内容的提问来源于stack exchange,提问作者Mohsen Mohsen

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 16:37:34