0

这可能是一个愚蠢的问题,但我一直在关注一些关于如何使用 Firebase 制作登录屏幕的 react native / expo 教程。我遵循的教程还制作了一个加载屏幕(使用加载状态),它将在 Firebase 连接时显示。不幸的是,加载状态对我来说永远不会结束,我不知道如何修复它。

这是我的 Navigator.js 文件:

import React, { useReducer } from "react";
import { View, ActivityIndicator } from 'react-native';

import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from "@react-navigation/stack";
import { createDrawerNavigator } from "@react-navigation/drawer";

import { AuthContext } from '../contexts/UserContext';
import { firebase } from "../utils/FirebaseConfig";

import Login from "../screens/Login";
import Signup from "../screens/Signup";
import Home from "../screens/Home";

const Drawer = createDrawerNavigator();
const RootStack = createStackNavigator();

export default AppNavigation = (props) => {

    const initialLoginState = {
        isLoading: true,
        user: null,
    };
    const loginReducer = (prevState, action) => {
        switch (action.type) {
            case 'LOGIN':
                return {
                    ...prevState,
                    user: action.user,
                    isLoading: false,
                };
            case 'LOGOUT':
                return {
                    ...prevState,
                    user: null,
                    isLoading: false,
                };
            case 'REGISTER':
                return {
                    ...prevState,
                    user: action.user,
                    isLoading: false,
                };
        }
    };
    const [loginState, dispatch] = useReducer(loginReducer, initialLoginState);
    const authContext = React.useMemo(() => ({
        signIn: async (email, password) => {

            return firebase
                .auth()
                .signInWithEmailAndPassword(email, password)
                .then(async (userCred) => {
                    dispatch({ type: 'LOGIN', user: userCred.user });
                    return true;
                }).catch((error) => {
                    if (error.code === "auth/user-disabled") {
                        alert("User disabled!");
                    }
                    if (error.code === "auth/invalid-email") {
                        alert("That email address is invalid!");
                    }
                    if (error.code === "auth/user-not-found") {
                        alert("User not found, please sign up!");
                    }
                    if (error.code === "auth/wrong-password") {
                        alert("Wrong password!");
                    }

                    return false;
                })
        },
        signOut: async () => {
            return firebase.auth().signOut().then(async () => {
                    dispatch({ type: 'LOGOUT' });
                });
        },
        signUp: (email, password) => {
            return firebase.auth().createUserWithEmailAndPassword(email, password).then((userCred) => {
                    dispatch({ type: 'REGISTER', user: userCred.user });
                }).catch((error) => {
                    if (error.code === "auth/email-already-in-use") {
                        alert("That email address is already in use!");
                    }
                    if (error.code === "auth/invalid-email") {
                        alert("That email address is invalid!");
                    }
                    if (error.code === "auth/operation-not-allowed") {
                        alert("Operation is not allowed!");
                    }
                    if (error.code === "auth/weak-password") {
                        alert("The password is too weak!");
                    }
                    return false;
                })
        }

    }), []);



    if (loginState.isLoading) {
        return (
            <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
                <ActivityIndicator size="large" color="grey" />
            </View>
        );
    }

    return (
        <AuthContext.Provider value={authContext}>
            <NavigationContainer>
                {loginState.user !== null ? (
                    <Drawer.Navigator >
                        <Drawer.Screen name="Home" user={loginState.user} component={Home} />
                    </Drawer.Navigator>
                ) :
                    (
                        <RootStack.Navigator headerMode='none'>
                            <RootStack.Screen name="Login" component={Login} />
                            <RootStack.Screen name="Signup" component={Signup} />
                        </RootStack.Navigator>
                    )
                }
            </NavigationContainer>
        </AuthContext.Provider>
    )

}

这是我的 Home.js 文件:

import React from 'react';
import { useContext } from 'react';
import { Text, TouchableOpacity, View } from 'react-native';
import { AuthContext } from "../contexts/UserContext";

function Home(props) {

    const { signOut } = useContext(AuthContext);

    return (
        <View style={{ flex: 1 }}>
            <Text>Welcome</Text>

            <Text>Email: {props.user?.email}</Text>
            <Text>uid: {props.user?.uid}</Text>
            <Text>displayName: {props.user?.displayName}</Text>
            <Text>photo: {props.user?.photoURL}</Text>

            <TouchableOpacity onPress={() => signOut()} style={{ flexDirection: "row", alignItems: "center", justifyContent: "center", width: "100%" }} >
                <Text style={{ fontWeight: "bold", fontSize: 18 }}>Logout</Text>
            </TouchableOpacity>


        </View>
    );
}

export default Home;

这是 Login.js 文件:

import React, { useContext, useState } from 'react';

import { KeyboardAvoidingView, View, Text, TextInput } from 'react-native';

import { AuthContext } from "../contexts/UserContext";


function Login(props) {
    const [data, setData] = useState({
        email: "",
        password: ""
    })
    const { signIn } = useContext(AuthContext);
    const emailInputChange = (val) => {
        setData({
            ...data,
            email: val
        })
    }
    const passwordChange = (val) => {
        setData({
            ...data,
            password: val
        });
    }
    const LoginHandle = () => {
        signIn(data.email, data.password)
    }
    return (
        <KeyboardAvoidingView>
            <View style={{ flex: 1 }}>
                <Text>Email: </Text>
                <View >
                    <TextInput
                        placeholder="Email"
                        autoCapitalize="none"
                        onChangeText={(val) => emailInputChange(val)}
                    />
                </View>
                <Text>Password: </Text>
                <View>
                    <TextInput
                        placeholder="Password"
                        autoCapitalize="none"
                        secureTextEntry={true}
                        onChangeText={(val) => passwordChange(val)}
                    />
                </View>

                <TouchableOpacity onPress={() => LoginHandle()} style={{ width: "100%", height: 50, justifyContent: "center", alignItems: "center", borderRadius: 10 }}>
                    <Text style={{ color: "#FFF", fontSize: 18, fontWeight: "bold" }}>Login</Text>
                </TouchableOpacity>

            </View>

        </KeyboardAvoidingView>
    );
}

export default Login;

最后,Signup.js 文件:

import React, { useContext, useState } from 'react';
import { KeyboardAvoidingView, View, Text, TextInput } from 'react-native';

import { AuthContext } from "../contexts/UserContext";

function Signup(props) {
    const [data, setData] = useState({
        email: "",
        password: ""
    })
    const { signUp } = useContext(AuthContext);
    const emailInputChange = (val) => {
        setData({
            ...data,
            email: val
        })
    }
    const passwordChange = (val) => {
        setData({
            ...data,
            password: val
        });
    }
    const SignupHandle = () => {
        signUp(data.email, data.password)
    }
    return (
        <KeyboardAvoidingView>
            <View style={{ flex: 1 }}>
                <Text>Email: </Text>
                <View >
                    <TextInput
                        placeholder="Email"
                        autoCapitalize="none"
                        onChangeText={(val) => emailInputChange(val)}
                    />
                </View>
                <Text>Password: </Text>
                <View>
                    <TextInput
                        placeholder="Password"
                        autoCapitalize="none"
                        secureTextEntry={true}
                        onChangeText={(val) => passwordChange(val)}
                    />
                </View>

                <TouchableOpacity onPress={() => SignupHandle()} style={{ width: "100%", height: 50, justifyContent: "center", alignItems: "center", borderRadius: 10 }}>
                    <Text style={{ color: "#FFF", fontSize: 18, fontWeight: "bold" }}>Signup</Text>
                </TouchableOpacity>

            </View>

        </KeyboardAvoidingView>
    );
}

export default Signup;
4

0 回答 0