React Navigation v5 + firebase身份验证

问题描述 投票:0回答:1

我正在尝试使用React Navigation v5,v4和switchNavigator进行身份验证,但是我的代码可以正常工作,但是现在我了解了问题,但不知道如何解决。

此功能组件在首次打开应用程序时呈现,并确定导航器显示的内容。这按预期方式显示,当打开应用程序时显示authnav或homenav,当我尝试登录(从authnav)然后导航到内部homenav的“主页”屏幕时出现问题,但我知道IsAuth不会重新呈现,因此我收到此错误,因此我的问题是如何在有更改时使IsAuth呈现。

enter image description here第一个组件已渲染

export type isAuthProps = ThemedComponentProps & ComponentProps;
const IsAuth: React.FC<RoutesProps> = (props: isAuthProps) => {
    let navigator: any;
    const { themedStyle, theme, ...rest } = props;
    const [user, setUser] = useState(null);
    const [loading, setLoading] = useState(true);
    const onAuthStateChanged = (currentUser: any) => {
        console.log("TCL: onAuthStateChanged -> currentUser", currentUser);
        if (!currentUser) {
            setUser(currentUser);
            setLoading(false);
        } else {
            if (!currentUser.emailVerified) {
                console.log("TCL: onAuthStateChanged -> currentUser.emailVerified", currentUser.emailVerified)
                setUser(null);
                setLoading(false);
            } else {
                setUser(currentUser);
                setLoading(false);
            }
        }
    };
    useEffect(() => {
        NavigationService.setNavigator(navigator);
        const subscriber = firebase.auth().onAuthStateChanged(onAuthStateChanged);
        return () => {
            subscriber();
        }; // unsubscribe on unmount
    }, []);

    if (loading) {
        return (<View style={themedStyle.container} >
            <LoadingIndicator size='large' />
        </View>);
    }

    return (
        <NavigationContainer theme={navigatorTheme} ref={(nav: any) => {
            navigator = nav;
        }}
        >
            {user ? <HomeTabsNavigator /> : <AuthNavigator />}
        </NavigationContainer>
    );
};

导航器

export const HomeTabsNavigator = (): React.ReactElement => {
    return (
        <BottomTab.Navigator
            screenOptions={TabBarVisibleOnRootScreenOptions}
            initialRouteName={'Home'}
            tabBar={props => <HomeBottom {...props} />}>
            <BottomTab.Screen name='Home' component={LayoutsNavigator} />
            <BottomTab.Screen name='Post' component={PostNavigator} />
            <BottomTab.Screen name='Favorites' component={FavoritesNavigator} />
            <BottomTab.Screen name='Themes' component={ThemesNavigator} />
            <BottomTab.Screen name='Settings' component={SettingsNavigator} />
        </BottomTab.Navigator>
    )
};

export const AuthNavigator = () => {
    return (
        <Stack.Navigator headerMode='none'>
            <Stack.Screen name='Signin' component={SigninContainer}></Stack.Screen>
            <Stack.Screen name='Signup' component={SignupContainer}></Stack.Screen>
            <Stack.Screen name='ForgotPassword' component={ForgotPasswordContainer}></Stack.Screen>
            <Stack.Screen name='SigninGoogle' component={SigninGoogleContainer}></Stack.Screen>
        </Stack.Navigator>
    );
};

我的登录按钮称呼这个传奇

export function* signinSaga(action: Signin) {
    try {
        const payload = action.payload;
        const response = yield firebase.auth().signInWithEmailAndPassword(payload.email, payload.password);
        const user = response.user;
        const token = yield firebase.auth().currentUser?.getIdToken();
        yield put(new SigninSuccess({ token, uid: user.uid }));
        yield NavigationService.navigate('Explore');
        yield showMessageSuccess({ code: 'Successfully login', message: 'Welcome to XXXX!' });
    } catch (e) {
        const error = errorParser(e);
        yield put(new SigninFail(error));
        yield showMessageDanger(error);
    }
}
reactjs firebase react-native firebase-authentication react-navigation
1个回答
0
投票

终于用redux做到了此导航器用于App.tsx

const AppNavigator = () => {
    const isAuth = useSelector(selectAuthUser);
    console.log("AppNavigator -> isAuth", isAuth);
    const didTryAutoLogin = useSelector(selectAuthDidTryLogin);
    console.log("AppNavigator -> didTryAutoLogin", didTryAutoLogin);

    return (
        <NavigationContainer>
            {isAuth && <HomeTabsNavigator />}
            {!isAuth && didTryAutoLogin && <AuthNavigator />}
            {!isAuth && !didTryAutoLogin && <IsAuthScreen />}
        </NavigationContainer>
    );
};

export default AppNavigator;

我创建了一个新的屏幕组件,我在Angular Typescript中使用了Action clases inspirit,因此,如果您使用的是Plan js,请正常调用该动作。

interface RoutesProps {
}

interface ComponentProps {
}
export type isAuthProps = ThemedComponentProps & ComponentProps;
const IsAuth: React.FC<RoutesProps> = (props: isAuthProps) => {
    const { themedStyle, theme, ...rest } = props;
    const dispatch = useDispatch();
    const onAuthStateChanged = (currentUser: any) => {
        if (!currentUser) {
            dispatch(new authActions.DidTryLogin());
        } else {
            if (!currentUser.emailVerified) {
                dispatch(new authActions.DidTryLogin());
            } else {
                dispatch(new authActions.SigninSuccess(currentUser));
            }
        }
    };
    useEffect(() => {

        const subscriber = firebase.auth().onAuthStateChanged(onAuthStateChanged);
        return () => {
            subscriber();
        }; // unsubscribe on unmount
    }, [dispatch]);

    return (<View style={themedStyle.container} >
        <LoadingIndicator size='large' />
    </View>);
};

export const IsAuthScreen = withStyles(IsAuth, (theme: ThemeType) => ({
    container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
    },
}));

减速器

case AuthActionTypes.SIGNIN_SUCCESS: {
            return {
                ...state,
                loading: false,
                error: null,
                user: action.payload,
                didTryLogin: true,
            };
        }
case AuthActionTypes.DID_TRY_LOGIN: {
            return {
                ...state,
                didTryLogin: true,
            };
        }

 case AuthActionTypes.LOGOUT: {
            return { ...INIT_STATE, didTryLogin: true }
        }

佐贺

export function* signinSaga(action: Signin) {
    try {
        const payload = action.payload;
        const response = yield firebase.auth().signInWithEmailAndPassword(payload.email, payload.password);
        const user = response.user;
        if (user.emailVerified) {
            yield put(new SigninSuccess({ user }));
            yield showMessageSuccess({ code: 'Successfully login', message: 'Welcome to XXXX!' });
        } else {
            const error = { code: 'Something go wrong', message: 'You need to verify your email first.' };
            yield put(new SigninFail(error));
            yield showMessageDanger(error);
        }
    } catch (e) {
        const error = errorParser(e);
        yield put(new SigninFail(error));
        yield showMessageDanger(error);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.