简体   繁体   English

如何在登录后根据用户的角色(提供者或客户)使用 React Native 和 Firebase/Firestore 渲染 iOS 应用程序的不同屏幕?

[英]How do I render different Screens of an iOS app with React Native and Firebase/Firestore based on a user's role (provider or customer) after login?

I'm creating an app with React Native and Firebase/Firestore, and I need the app to show different screens based on the role of the user's account (Provider or Customer).我正在使用 React Native 和 Firebase/Firestore 创建一个应用程序,我需要该应用程序根据用户帐户(提供商或客户)的角色显示不同的屏幕。 After a user logs into their account, the app should check their role data from Firebase and render a different screen based on it.用户登录他们的帐户后,应用程序应该从 Firebase 检查他们的角色数据并根据它呈现不同的屏幕。 So the app will first evaluate the condition to see if they're logged in. Then it will evaluate the condition to see if they're a Provider or Customer and then render the proper screen (either the Login, ProviderHomeScreen, or CustomerHomeScreen).因此,应用程序将首先评估条件以查看他们是否已登录。然后它将评估条件以查看他们是提供者还是客户,然后呈现正确的屏幕(登录、ProviderHomeScreen 或 CustomerHomeScreen)。

I've tried to use the condition:我尝试使用以下条件:

const user = firebase.auth().currentUser;
var role;

  if (user != null) {
    role = user.role;
    console.log(role);
  }

  if (isLoggedIn) {
    if (user.role === 'provider') {
      return (
        <NavigationContainer>
          <ProviderStack.Navigator>
            <Stack.Navigator>
              <Stack.Screen
                name={'Provider Home'}
                component={ProviderHomeTabNavigator}
                options={{
                  headerShown: false,
                }}
              />
            </Stack.Navigator>
          </ProviderStack.Navigator>
        </NavigationContainer>
      );
    } else {
      return (
        <NavigationContainer>
          <CustomerStack.Navigator>
            <Stack.Screen
              name={'Customer Home'}
              component={CustomerHomeTabNavigator}
              options={{
                headerShown: false,
              }}
            />
            <Stack.Screen
              name={'Search'}
              component={SearchScreen}
              options={{
                title: 'Search Availa Providers',
              }}
            />
          </CustomerStack.Navigator>
        </NavigationContainer>
      );
    }
  }
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Login" component={LoginScreen} />
        <Stack.Screen
          name="Customer Sign-up"
          component={CustomerRegistrationScreen}
        />
        <Stack.Screen
          name="Provider Sign-up"
          component={ProviderRegistrationScreen}
        />
      </Stack.Navigator>
    </NavigationContainer>

but when I console.log the user.role, it says undefined in the console, and the app just renders the CustomerHomeScreen with the CustomerHomeTabNavigator.但是当我对 user.role 进行控制台登录时,它在控制台中显示未定义,并且该应用程序仅使用 CustomerHomeTabNavigator 呈现 CustomerHomeScreen。 Please help me successfully access the role data of the currently signed-in user from Firestore and create conditions to render the proper screens for the proper role of the users.请帮助我从 Firestore 成功访问当前登录用户的角色数据,并创造条件为用户的正确角色呈现正确的屏幕。

Right now, this is what my code looks like for App.js:现在,这就是我的 App.js 代码的样子:

import 'react-native-gesture-handler';
import React, {useEffect, useState} from 'react';
import {View, Text} from 'react-native';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {createStackNavigator} from '@react-navigation/stack';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import CustomerHomeScreen from '../Availa/src/Customer/screens/Home/index';
import Fontisto from 'react-native-vector-icons/Fontisto';
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import FontAwesome5 from 'react-native-vector-icons/FontAwesome5';
import Feather from 'react-native-vector-icons/Feather';
import AntDesign from 'react-native-vector-icons/AntDesign';
import Ionicons from 'react-native-vector-icons/Ionicons';
import {firebase} from '../Availa/src/firebase/config';
import 'firebase/auth';
import firestore from '@react-native-firebase/firestore';
import 'firebase/firestore';
import 'react-native-gesture-handler';
Fontisto.loadFont();
FontAwesome.loadFont();
Feather.loadFont();
AntDesign.loadFont();
Ionicons.loadFont();
import SearchScreen from '../Availa/src/Customer/screens/SearchScreen/index';
import ProfileScreen from '../Availa/src/Customer/screens/ProfileScreen/index';

import {
  LoginScreen,
  CustomerRegistrationScreen,
  ProviderRegistrationScreen,
} from './src/screens';
import 'firebase/auth';
import {decode, encode} from 'base-64';
if (!global.btoa) {
  global.btoa = encode;
}
if (!global.atob) {
  global.atob = decode;
}
const ProviderStack = createNativeStackNavigator();
const ProviderStackScreen = () => {
  return (
    <ProviderStack.Navigator>
      <Stack.Navigator>
        <Stack.Screen
          name={'Home'}
          component={ProviderHomeTabNavigator}
          options={{
            headerShown: false,
          }}
        />
      </Stack.Navigator>
    </ProviderStack.Navigator>
  );
};
const ProviderTab = createBottomTabNavigator();
const ProviderHomeTabNavigator = () => {
  return (
    <Tab.Navigator
      tabBarOptions={{
        activeTintColor: '#007FFF',
      }}>
      <Tab.Screen
        name={'Provider'}
        component={ProviderHomeScreen}
        options={{
          tabBarIcon: ({color}) => (
            <Fontisto name="home" size={25} color={color} />
          ),
        }}
      />
      <Tab.Screen
        name={'My List'}
        component={ProviderHomeScreen}
        options={{
          tabBarIcon: ({color}) => (
            <FontAwesome name="heart-o" size={25} color={color} />
          ),
        }}
      />
      <Tab.Screen
        name={'Appointments'}
        component={ProviderHomeScreen}
        options={{
          tabBarIcon: ({color}) => (
            <AntDesign name="calendar" size={25} color={color} />
          ),
        }}
      />
      <Tab.Screen
        name={'Messages'}
        component={ProviderHomeScreen}
        options={{
          tabBarIcon: ({color}) => (
            <Feather name="message-square" size={25} color={color} />
          ),
        }}
      />
      <Tab.Screen
        name={'Profile'}
        component={ProfileScreen}
        options={{
          tabBarIcon: ({color}) => (
            <Ionicons name="person-circle-outline" size={25} color={color} />
          ),
        }}
      />
    </Tab.Navigator>
  );
};

const CustomerStack = createNativeStackNavigator();
const CustomerStackScreen = () => {
  return (
    <CustomerStack.Navigator>
      <Stack.Navigator>
        <Stack.Screen
          name={'Home'}
          component={CustomerHomeTabNavigator}
          options={{
            headerShown: false,
          }}
        />
      </Stack.Navigator>
    </CustomerStack.Navigator>
  );
};
const Tab = createBottomTabNavigator();
const CustomerHomeTabNavigator = () => {
  return (
    <Tab.Navigator
      tabBarOptions={{
        activeTintColor: '#1cd478',
      }}>
      <Tab.Screen
        name={'Home'}
        component={CustomerHomeScreen}
        options={{
          tabBarIcon: ({color}) => (
            <Fontisto name="home" size={25} color={color} />
          ),
        }}
      />
      <Tab.Screen
        name={'My List'}
        component={CustomerHomeScreen}
        options={{
          tabBarIcon: ({color}) => (
            <FontAwesome name="heart-o" size={25} color={color} />
          ),
        }}
      />
      <Tab.Screen
        name={'Appointments'}
        component={CustomerHomeScreen}
        options={{
          tabBarIcon: ({color}) => (
            <AntDesign name="calendar" size={25} color={color} />
          ),
        }}
      />
      <Tab.Screen
        name={'Messages'}
        component={CustomerHomeScreen}
        options={{
          tabBarIcon: ({color}) => (
            <Feather name="message-square" size={25} color={color} />
          ),
        }}
      />
      <Tab.Screen
        name={'Profile'}
        component={ProfileScreen}
        options={{
          tabBarIcon: ({color}) => (
            <Ionicons name="person-circle-outline" size={25} color={color} />
          ),
        }}
      />
    </Tab.Navigator>
  );
};

const chooseScreen = user => {
  if (user?.role === 'provider') {
    ProviderStackScreen();
  }
  CustomerStackScreen();
};

const Stack = createStackNavigator();

export default function App() {
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const [loading, setLoading] = useState(true);
  const firestore = firebase.firestore;
  const auth = firebase.auth;
  const user = firebase.auth().currentUser;

  // //to check if Firebase has been initialized
  if (!firebase.apps.length) {
    firebase.initializeApp(firebaseConfig);
  } else {
    firebase.app();
  }

  firebase.auth().onAuthStateChanged(user => {
    if (user != null) {
      setIsLoggedIn(true);
    } else {
      setIsLoggedIn(false);
    }
  });

  var role;

  if (user != null) {
    role = user.role;
    console.log(role);
  }

  if (isLoggedIn) {
    if (user.role === 'provider') {
      return (
        <NavigationContainer>
          <ProviderStack.Navigator>
            <Stack.Navigator>
              <Stack.Screen
                name={'Provider Home'}
                component={ProviderHomeTabNavigator}
                options={{
                  headerShown: false,
                }}
              />
            </Stack.Navigator>
          </ProviderStack.Navigator>
        </NavigationContainer>
      );
    } else {
      return (
        <NavigationContainer>
          <CustomerStack.Navigator>
            <Stack.Screen
              name={'Customer Home'}
              component={CustomerHomeTabNavigator}
              options={{
                headerShown: false,
              }}
            />
            <Stack.Screen
              name={'Search'}
              component={SearchScreen}
              options={{
                title: 'Search Availa Providers',
              }}
            />
          </CustomerStack.Navigator>
        </NavigationContainer>
      );
    }
  }
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Login" component={LoginScreen} />
        <Stack.Screen
          name="Customer Sign-up"
          component={CustomerRegistrationScreen}
        />
        <Stack.Screen
          name="Provider Sign-up"
          component={ProviderRegistrationScreen}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );

Also, this is what my LoginScreen.js looks like:此外,这就是我的 LoginScreen.js 的样子:

import React, {useState} from 'react';
import {Image, Text, TextInput, TouchableOpacity, View} from 'react-native';
import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
import styles from './styles';
import {firebase} from '../../firebase/config';

export default function LoginScreen({navigation}) {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const onLoginPress = () => {
    firebase
      .auth()
      .signInWithEmailAndPassword(email, password)
      .then(response => {
        const uid = response.user.uid;
        const usersRef = firebase.firestore().collection('users');
        usersRef
          .doc(uid)
          .get()
          .then(firestoreDocument => {
            if (!firestoreDocument.exists) {
              alert('User does not exist');
              return;
            }
            const user = firestoreDocument.data();
            if (user.role === 'provider') {
              navigation.navigate('Provider Home', {user});
            } else {
              navigation.navigate('Customer Home', {user});
            }
          })
          .catch(error => {
            alert(error);
          });
      })
      .catch(error => {
        alert(error);
      });
  };

  return (
    <View style={styles.container}>
      <KeyboardAwareScrollView
        style={{flex: 1, width: '100%'}}
        keyboardShouldPersistTaps="always">
        <Image
          style={styles.logo}
          source={require('../../../assets/availalogo.png')}
        />
        <TextInput
          style={styles.input}
          placeholder="Email"
          placeholderTextColor="#aaaaaa"
          onChangeText={text => setEmail(text)}
          value={email}
          underlineColorAndroid="transparent"
          autoCapitalize="none"
        />
        <TextInput
          style={styles.input}
          placeholderTextColor="#aaaaaa"
          secureTextEntry
          placeholder="Password"
          onChangeText={text => setPassword(text)}
          value={password}
          underlineColorAndroid="transparent"
          autoCapitalize="none"
        />
        <TouchableOpacity style={styles.button} onPress={() => onLoginPress()}>
          <Text style={styles.buttonTitle}>Log in</Text>
        </TouchableOpacity>

        <Text style={styles.footerText}>Don't have an account?</Text>
        <TouchableOpacity
          style={{
            backgroundColor: '#ED2939', //#118C4F?
            marginLeft: 30,
            marginRight: 30,
            marginTop: 20,
            height: 48,
            borderRadius: 5,
            alignItems: 'center',
            justifyContent: 'center',
          }}
          onPress={() => navigation.navigate('Provider Sign-up')}>
          <Text style={{color: 'white', fontSize: 16, fontWeight: 'bold'}}>
            Sign Up as Availa Provider
          </Text>
        </TouchableOpacity>
        <TouchableOpacity
          style={{
            backgroundColor: '#007FFF',
            marginLeft: 30,
            marginRight: 30,
            marginTop: 20,
            height: 48,
            borderRadius: 5,
            alignItems: 'center',
            justifyContent: 'center',
          }}
          onPress={() => navigation.navigate('Customer Sign-up')}>
          <Text style={{color: 'white', fontSize: 16, fontWeight: 'bold'}}>
            Sign Up as Customer
          </Text>
        </TouchableOpacity>
      </KeyboardAwareScrollView>
    </View>
  );
}

Are you adding the role in custom claims?您是否在自定义声明中添加角色?

if so you need to get the the claims from getIdTokenResult如果是这样,您需要从 getIdTokenResult 获取声明

firebase.auth().currentUser.getIdTokenResult()
.then((idTokenResult) => {
  const role = idTokenResult.claims.role;
})
.catch((error) => {
  console.log(error);
});

Also I personally keep the firebase initialization outside of the component and此外,我个人将 firebase 初始化保留在组件之外,并且

firebase.auth().onAuthStateChanged(user => {
  if (user != null) {
    setIsLoggedIn(true);
  } else {
    setIsLoggedIn(false);
  }
});

inside useEffect , so instead of setIsLoggedIn would do setUser and in your case after you get the role you can set it in a different state.useEffect内部,因此setIsLoggedIn将代替setUser ,在您获得角色后,您可以将其设置为不同的状态。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 安装 react-native-firebase/app 后,Build 将在 react-native ios 中失败 - After installing react-native-firebase/app it's Build will failed in react-native ios 如何在iOS上的react本机应用程序上检查网络流量? - How do I inspect network traffic on a react native app on iOS? 如何为本机iOS应用程序创建测试用户? - How do I create a test user for a native iOS app? 如何使用iOS / Swift中的startPasswordAuthentication委托切换到登录屏幕,以便基于Cognito用户池登录? - How do I switch to login screen with the startPasswordAuthentication delegate in iOS/Swift for Cognito User Pools based login? 如何在React Native中的iOS状态栏前面渲染视图? - How do I render a view in front of the iOS status bar in React Native? React-Native:如何缩放字体大小以支持Android和iOS中的许多不同分辨率和屏幕? - React-Native: How to scale font size to support many different resolutions and screens in both Android and iOS? 在 React Native 中处理不同的屏幕 - Handle different Screens in React Native 本机iOS应用程序:如何使用iOS 5检索Twitter用户ID? - Native iOS app: How do I retrieve the Twitter user ID with iOS 5? 如何使用Windows上的快速通道将本机iOS应用程序部署到应用程序商店? - How do I deploy react native iOS app to app store with fast lane on windows? 如何将Facebook登录UI添加到我的React Native应用程序中? - How do I add the facebook login UI to my React Native app?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM