我尝试在客户端连接到应用程序后制作不同的屏幕。连接到 Firebase 可以顺利进行。我可以在我的数据库中看到新用户。然而,每次我尝试将导航器和 Tab.Screens 放入 AuthenticatedScreen const 中时,我什么也得不到。
但是,当我放置一个简单的 View 时,它就可以工作了。
代码:
import React, { useEffect, useState } from 'react';
import { ScrollView, StyleSheet, View, Text } from 'react-native';
import { initializeApp } from 'firebase/app';
import { getAuth, onAuthStateChanged, signOut, signInWithEmailAndPassword, createUserWithEmailAndPassword, initializeAuth, getReactNativePersistence } from 'firebase/auth';
import { NavigationContainer } from '@react-navigation/native';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { UserProvider, useUser } from './UserContext';
import AuthScreen from './AuthScreen';
import AsyncStorage from '@react-native-async-storage/async-storage';
import Homescreen from './screens/Homescreen';
const firebaseConfig = {
apiKey: "xxxxx",
authDomain: "xxxx",
projectId: "xxxx",
storageBucket: "xxxx",
messagingSenderId: "xxxx",
appId: "xxxx"
};
const app = initializeApp(firebaseConfig);
// Utilisation de initializeAuth avec AsyncStorage
const auth = initializeAuth(app, {
persistence: getReactNativePersistence(AsyncStorage)
});
const Tab = createBottomTabNavigator();
const AuthenticatedScreen = () => {
const { user } = useUser();
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={Homescreen} />
</Tab.Navigator>
);
};
const App = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [isLogin, setIsLogin] = useState(true);
const { user, setUser } = useUser();
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (user) => {
setUser(user);
});
return () => unsubscribe();
}, [auth]);
const handleAuthentication = async () => {
try {
if (user) {
await signOut(auth);
} else {
if (isLogin) {
await signInWithEmailAndPassword(auth, email, password);
} else {
await createUserWithEmailAndPassword(auth, email, password);
}
}
} catch (error) {
console.error('Authentication error:', error.message);
}
};
return (
<ScrollView contentContainerStyle={styles.container}>
{user ? (
<AuthenticatedScreen />
) : (
<AuthScreen
email={email}
setEmail={setEmail}
password={password}
setPassword={setPassword}
isLogin={isLogin}
setIsLogin={setIsLogin}
handleAuthentication={handleAuthentication}
/>
)}
</ScrollView>
);
};
const styles = StyleSheet.create({
container: {
flexGrow: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 16,
backgroundColor: '#f0f0f0',
},
});
export default () => (
<UserProvider>
<App />
</UserProvider>
);
我找到了答案。问题是滚动视图。它似乎干扰了 React Navigator
删除这个:
<ScrollView contentContainerStyle={styles.container}>
{user ? (
<AuthenticatedScreen />
) : (
<AuthScreen
email={email}
setEmail={setEmail}
password={password}
setPassword={setPassword}
isLogin={isLogin}
setIsLogin={setIsLogin}
handleAuthentication={handleAuthentication}
/>
)}
</ScrollView>
并更改为:
if (user) {
return <AuthenticatedScreen />
}
return (
<AuthScreen
email={email}
setEmail={setEmail}
password={password}
setPassword={setPassword}
isLogin={isLogin}
setIsLogin={setIsLogin}
handleAuthentication={handleAuthentication}
/>
);
最终的代码是:
import React, { useEffect, useState } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { StyleSheet, View, Text, Button } from 'react-native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { initializeApp } from 'firebase/app';
import { getAuth, onAuthStateChanged, signOut, signInWithEmailAndPassword, createUserWithEmailAndPassword, initializeAuth, getReactNativePersistence } from 'firebase/auth';
import { UserProvider, useUser } from './UserContext';
import AuthScreen from './AuthScreen';
import AsyncStorage from '@react-native-async-storage/async-storage';
import Homescreen from './screens/Homescreen';
import Calendar from './screens/Calendar';
const Stack = createNativeStackNavigator();
const firebaseConfig = {
apiKey: "xxxx",
authDomain: "xxxx",
projectId: "xxxx",
storageBucket: "xxxx",
messagingSenderId: "xxxx",
appId: "xxxx"
};
const app = initializeApp(firebaseConfig);
// Utilisation de initializeAuth avec AsyncStorage
const auth = initializeAuth(app, {
persistence: getReactNativePersistence(AsyncStorage)
});
const AuthenticatedScreen = () => {
const { user } = useUser();
const handleLogout = async () => {
try {
await signOut(auth);
} catch (error) {
console.error('Logout error:', error.message);
}
};
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={Homescreen} />
<Stack.Screen name="Calendar" component={Calendar} />
</Stack.Navigator>
</NavigationContainer>
);
};
const App = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [isLogin, setIsLogin] = useState(true);
const { user, setUser } = useUser();
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (user) => {
setUser(user);
});
return () => unsubscribe();
}, [auth]);
const handleAuthentication = async () => {
try {
if (user) {
await signOut(auth);
} else {
if (isLogin) {
await signInWithEmailAndPassword(auth, email, password);
} else {
await createUserWithEmailAndPassword(auth, email, password);
}
}
} catch (error) {
console.error('Authentication error:', error.message);
}
};
if (user) {
return <AuthenticatedScreen />
}
return (
<View style={styles.container}>
<AuthScreen
email={email}
setEmail={setEmail}
password={password}
setPassword={setPassword}
isLogin={isLogin}
setIsLogin={setIsLogin}
handleAuthentication={handleAuthentication}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flexGrow: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 16,
backgroundColor: '#f0f0f0',
},
});
export default () => (
<UserProvider>
<App />
</UserProvider>
);