我正在使用React Native和Firebase/Firestore创建一个应用程序,我需要该应用程序根据用户帐户(提供商或客户)的角色显示不同的屏幕。用户登录帐户后,应用程序应该从Firebase检查他们的角色数据,并根据这些数据呈现不同的屏幕。所以应用程序首先会评估他们的状态,看看他们是否登录了。然后,它将评估条件,看看它们是提供者还是客户,然后呈现适当的屏幕(Login、providerhomesscreen或customerhomesscreen)。
我试过使用条件:
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>
但是当我console.log用户。角色,它在控制台中说未定义,应用只是用CustomerHomeTabNavigator渲染CustomerHomeScreen。请帮助我成功地从Firestore访问当前登录用户的角色数据,并创建条件,以便为用户的适当角色呈现适当的屏幕。
现在,这是我的代码看起来像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>
);
同样,这是我的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>
);
}
是否在自定义声明中添加角色?
如果是,则需要从getIdTokenResult
获取声明firebase.auth().currentUser.getIdTokenResult()
.then((idTokenResult) => {
const role = idTokenResult.claims.role;
})
.catch((error) => {
console.log(error);
});
我个人也把firebase初始化放在组件和
之外。firebase.auth().onAuthStateChanged(user => {
if (user != null) {
setIsLoggedIn(true);
} else {
setIsLoggedIn(false);
}
});
在useEffect
中,所以setIsLoggedIn
将代替setUser
,在你的情况下,当你获得角色后,你可以将它设置在不同的状态。