Реагировать на навигацию v5 + аутентификация на базе firebase - PullRequest
0 голосов
/ 06 марта 2020

Я пытаюсь добиться аутентификации с помощью реакционной навигации 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);
    }
}

1 Ответ

0 голосов
/ 06 марта 2020

Ну наконец-то получилось с редуксом. Этот навигатор используется в 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;

Я создаю новый экранный компонент, я использую Action clamis inspirit в Angular Typescript, так что если вы используете планируйте 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);
    }
}
...