Firebase с React: onAuthStateChanged получает контроль после входа в систему - PullRequest
0 голосов
/ 06 февраля 2020

Я разработал приложение реагирования с Firebase в качестве бэк-энда. Я имею App.tsx обрабатывать всю навигацию с аутентификацией и Login.tsx, чтобы сделать логин```

App.tsx

const App: React.FC = () => {

    const [authentication, setAuthState] = useState({
        authenticated: !!auth.currentUser,
        initializing: true,
        emailVerified: auth.currentUser ? auth.currentUser.emailVerified : false,
        landingPage: '/login'
    });

    React.useEffect(() => auth.onAuthStateChanged(user => {
        //TODO need to handle authorization here
        console.log("Auth state changed!", user);
        if (user) {
            setAuthState({
                authenticated: true,
                initializing: false,
                emailVerified:  user.emailVerified,
                landingPage: '/nav'
            });
        } else {
            setAuthState({
                authenticated: false,
                initializing: false,
                emailVerified:  false,
                landingPage: '/login'
            });
        }
    }), []);
    if (authentication.initializing) {
        console.log("App initializing screen!");
        return <div style={{textAlign: 'center', paddingTop: '5%'}}>
            <div style={{display: 'inline-block'}}>
                <Spin/>
            </div>
        </div>
    }

    //TODO if already loggedin navigate without loading
    // if(authentication.authenticated){
    //     const history = useHistory();
    //     console.log("Automatically landing after login event!!");
    //
    //     // history.push("/nav");
    //     //find dynamic landing page
    //     history.push("/nav");
    // }

    return (
        <BrowserRouter>
            <div>
                <Switch>
                    <PublicRoute path="/" component={Welcome} exact isAuthorized={true}/>
                    <PublicRoute path="/login" component={NewLogin} exact isAuthorized={true}/>
                    <PrivateRoute path="/nav" component={NavigationBar} exact isSignedIn={authentication.authenticated}/>
                    <PrivateRoute path="/dashboard" component={AnalyticsDashBoard} exact isSignedIn={authentication.authenticated}/>
                    <PrivateRoute path="/onboarding" component={OnBoarding} exact isSignedIn={authentication.authenticated}/>
                </Switch>
            </div>
        </BrowserRouter>
    );
};

export default App;

Логин. tsx

const MyLogin: React.FC = (props: any) => {
    const {getFieldDecorator} = props.form;
    let [loginState, setLoginState] = useState({
        loading:false,
        loggedIn:!!auth.currentUser
    });
    const handleSuccessfulLogin = () => {
        console.log("coming for successful login");
        message.success("Login Successful!");
        setLoginState({
            loading:false,
            loggedIn:true
        });
    }

    const handleLogin = (e: any) => {
        e.preventDefault();
        setLoginState({
           loading: true,
           loggedIn: false
        });
        console.log("coming for login");
        props.form.validateFields(['loginMail', 'loginPassword'], (err: object, values: object) => {
            if (err) {
                setLoginState({
                    loading: false,
                    loggedIn: false
                });
                return;
            }

            // @ts-ignore
            auth.signInWithEmailAndPassword(values.loginMail, values.loginPassword)
                .then( () => handleSuccessfulLogin)
                .catch(function (error) {
                    message.error(error.code + ' - ' + error.message);
                    console.log('Sign in failed!', error.code, ' and ', error.message);
                    setLoginState({
                        loading: false,
                        loggedIn: false
                    });
                });
        });

    }


    if (loginState.loading){
        console.log("Going in loading state");
        return <div style={{textAlign: 'center', paddingTop: '5%'}}>
            <div style={{display: 'inline-block'}}>
                <Spin/>
            </div>
        </div>
    }

    return (
        <div style={{textAlign: 'center', paddingTop: '5%'}}>
            <div style={{display: 'inline-block'}}>
...

Когда я пытаюсь войти с помощью signInWithEmailAndPassword, происходит вход, но я вызвал метод handleSuccessfullLogin, если вход успешный. Проблема здесь заключается в том, что после входа в систему запускается наблюдатель с аутентификацией, который находится внутри App.tsx, но не все строки в handlesuccesfulLogin выполнены. Также контролируйте, чтобы не возвращаться в Login.tsx.

Как я могу справиться с этим сценарием, как убедиться, что все строки в моей функции работают независимо от наблюдателей.

...