साइन इन करते समय, रीडायरेक्ट onAuthStateChanged() के स्टेट अपडेट की तुलना में तेज़ होता है। आप उस व्यवहार को कैसे संभालते हैं?

// firebase/index.js
import React, { createContext } from 'react'
import * as firebase from "firebase/app";
import "firebase/firestore";
import "firebase/auth";

const firebaseConfig = {
    apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
    authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
    projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID
};

const app = firebase.initializeApp(firebaseConfig);
export default app

export const FirebaseContext = createContext({})
export const FirebaseProvider = FirebaseContext.Provider
// index.js

import firebase, { FirebaseProvider } from './firebase'

            <FirebaseProvider value={firebase}>
                <App />
            </FirebaseProvider>
// App.js

const App = () => {
    const firebase = useContext(FirebaseContext)
    const [auth, setAuth] = useState({ loading: true, user: null })

    useEffect(() => {
        const unsubscribe = firebase.auth().onAuthStateChanged(function (user) {
            console.log(user)
            if (user) {
                console.log("logged in")
                setAuth({ loading: false, user })
            } else {
                console.log("not logged in")
                setAuth({ ...auth, loading: false })
            }
        });

        return () => {
            unsubscribe();
        }
    }, [])

    return (
        <BrowserRouter>
            ...

                <Switch>
                    <Route exact path="/signup" component={SignUp} />
                    <Route exact path="/signin" component={SignIn} />
                    <Route exact path="/signout" component={SignOut} />
                    <Route exact path="/public" component={Public} />
                    <PrivateRoute exact path="/private" auth={auth} comp={Private} />
// signin.js

import React, { useState, useContext } from 'react';
import { withRouter } from "react-router-dom";

import { FirebaseContext } from '../firebase'

const SignIn = ({ history }) => {
    const [state, setState] = useState({})
    const [alert, setAlert] = useState(false)

    const firebase = useContext(FirebaseContext)

    const signIn = () => {
        firebase
            .auth()
            .signInWithEmailAndPassword(state.email, state.password)
            .then(() => {
                history.push("/private")
            })
            .catch(function (error) {
                ...
            })
    }

    return (
        ...
    )
}

export default withRouter(SignIn)
// PrivateRoute.js

const PrivateRoute = ({ auth, comp: Component, ...rest }) => {
    return (
        <Route
            {...rest}
            render={props => 
                auth.loading
                    ? <Loading on={true} />
                    : !!auth.user
                        ? <Component {...props} />
                        : <Redirect to={"/signin"} />
            }
        />
    )
}

जब मैं सफलतापूर्वक साइन इन करता हूं (कोई त्रुटि संदेश नहीं है, और नेटवर्क getAccountInfo उपयोगकर्ता जानकारी के साथ प्रतिक्रिया दे रहा है), history.push रीडायरेक्ट कर रहा है लेकिन PrivateRoute मुझे इसके बजाय फिर से /signin पर रीडायरेक्ट कर रहा है। /private मार्ग। अगर मैं मैन्युअल रूप से यूआरएल बदलता हूं और /private रूट लोड करता हूं, तो मैं लॉग इन हूं।

यह कंसोल है:

// go to /private when not logged in -> redirected to /signin = OK

App.js: null
App.js: not logged in
PrivateRoute.js: {loading: false, user: null}

// on /signin page, fill form and submit

PrivateRoute.js: {loading: false, user: null}
App.js: P {N: Array(0), l: ... }
App.js: logged in

// go to /private by typing it in the browser

PrivateRoute.js: {loading: true, user: null}
App.js: P {N: Array(0), l: ... }
App.js: logged in
PrivateRoute.js: {loading: false, user: P { ... }} <-- the /private page is now rendered

मैं समझता हूं कि सफलतापूर्वक साइन इन करते समय, onAuthStateChanged() के पास auth स्थिति को पॉप्युलेट करने का समय होने से पहले मुझे पुनर्निर्देशित किया जाता है।

मुझे इसे कैसे नियंत्रित करना चाहिए? मैंने बिना किसी सफलता के बहुत सारे समाधान की कोशिश की :(

0
Binajmen 14 जून 2020, 10:42

1 उत्तर

सबसे बढ़िया उत्तर

UseEffect हमेशा पहले रेंडर के बाद चलेगा, इसलिए आप हमेशा लॉगआउट स्थिति में फंस जाएंगे जो लॉगिन और निजी पेज के बीच तेजी से पुनर्निर्देशन की ओर जाता है। आपको यूजर ऑथेंटिकेशन डेटा को लोकलस्टोरेज पर रखना चाहिए और रेंडर करने से पहले इसका तुरंत इस्तेमाल करना चाहिए (इसे यूज इफेक्ट पर सेट नहीं करना चाहिए); ताकि यदि उपयोगकर्ता पहले ही प्रमाणित हो चुका है तो आपको हर बार इस डेटा को लाने की आवश्यकता नहीं होगी।

const [auth, setAuth] = useState({ loading: true, user: localStorage.getItem('user')})

मिस रीडायरेक्शन को रोकने के लिए लॉगआउट या असफल प्रमाणीकरण के बाद आपको लोकलस्टोरेज को भी साफ करना होगा।

2
Kerem atam 14 जून 2020, 08:41