【问题标题】:React navigation v5 + firebase authenticationReact 导航 v5 + firebase 身份验证
【发布时间】:2020-03-06 11:02:18
【问题描述】:

我正在尝试使用 react navigation v5 实现身份验证,使用 v4 和 switchNavigator 我的代码正在运行,但现在我明白了我遇到的问题但不知道如何解决它。

此功能组件在第一次打开应用程序时呈现并确定导航器显示的内容。这可以按预期工作,在打开应用程序时显示 authnav 或 homenav 当我尝试登录(从 authnav)然后导航到内部 homenav 的“主”屏幕时出现问题,但我知道 IsAuth 没有重新渲染所以我收到了这个错误,所以我的问题是如何在有变化时渲染 IsAuth。

渲染的第一个组件

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】:

    终于用 redux 搞定了 这个 Navigator 在 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);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-10
      • 2017-07-12
      • 2016-12-25
      相关资源
      最近更新 更多