JavaEar 专注于收集分享传播有价值的技术资料

Firebase Authentication - How To Deal With Delay

I have set-up my Firebase project as per the video from David East, as below with this in my app.js file. I have removed my config parameters.

#topName refers to an element on the page that displays the authenticated user's username. Unfortunately what happens is that someone logs in, or is logged in and goes to the page, it initially displays guest and then after some time it switches to the username of that user. This is quick (<500ms) but causes the page to render twice which is confusing.

How can I avoid this, do I need to store something in local storage?

    (function() { 

    //Initialise Firebase
    var config = {
        apiKey: "",
        authDomain: "",
        databaseURL: "",
        projectId: "",
        storageBucket: "",
        messagingSenderId: ""
    };

    firebase.initializeApp(config);

    //Add a realtime listener.
    firebase.auth().onAuthStateChanged(firebaseUser => {
        if (firebaseUser) {
            console.log(firebaseUser);
            $('#topName').text(firebaseUser.email);
        }
        else
        {
            console.log('not logged in');
            $('#topName').text("Guest");
        }
    });




}());

2个回答

    最佳答案
  1. This is normal, it happens since the data that is being entered is being sent to the Firebase server, then you wait for a response from Firebase to check if this email is authenticated or not. Also internet connection can effect this.

    So lots of stuff are happening in the background, to solve this maybe add a loading spinner widget, or try and store the credentials locally.

    To solve this you can use localStorage example:

    localStorage.setItem("lastname", "userx"); //store data
    
    document.getElementById("result").innerHTML = localStorage.getItem("lastname") //to retrieve
    

    For more info check this: https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage

    Or you can use sessionStorage, more info here: https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage

  2. 参考答案2
  3. i solved this with the next code, just show a loader component while waiting for auth.onAuthStateChanged, the var has three values null, true and false.

    const Routes = () => {
      const dispatch = useDispatch();
    
      // firebase observer for user auth
      useEffect(() => {
        let unsubscribeFromAuth = null;
        unsubscribeFromAuth = auth.onAuthStateChanged(user => {
          if (user) {
            dispatch(setCurrentUser(user));
          } else {
            dispatch(clearCurrentUser());
          }
        });
        return () => unsubscribeFromAuth();
      }, [dispatch]);
    
      return (
        <Switch>
          <Route exact path="/" component={Dashboard} />
          <Route path="/signin">
            <SignIn />
          </Route>
          <ProtectedRoute path="/protected">
            <Dashboard />
          </ProtectedRoute>
          <Route path="*">
            <NoMatch />
          </Route>
        </Switch>
      );
    };
    
    const ProtectedRoute = ({ children, ...rest }) => {
      const currentUser = useSelector(state => state.auth.currentUser);
      if (currentUser === null) {
        // handle the delay in firebase auth info if current user is null show a loader if is false user sign out
        // TODO create a loading nice component
        return <h1>Loading</h1>;
      }
      return (
        <Route
          // eslint-disable-next-line react/jsx-props-no-spreading
          {...rest}
          render={({ location }) =>
            currentUser ? (
              children
            ) : (
              <Redirect
                to={{
                  pathname: '/signin',
                  state: { from: location }
                }}
              />
            )
          }
        />
      );
    };
    
    export default Routes;