title: How to handle Firebase onAuthStateChanged in a React app and route users accordingly?
body: <p>I'm working on a React web app that is integrated with Firebase and I'm trying to authenticate my users. I have setup my route to display Home component if the user is authenticated and the Login page otherwise. But when my app first loads, it shows the Login page and it takes a second or two for it to recognize the user has actually been authenticated and then it switches to the Home page. It just seems messy and I'm guessing I'm not handling onAuthStateChanged quite well or fast enough. In my App component, I am subscribed to a ReactObserver that signals when auth state has changed. What can I do to avoid this weird behaviour?</p>
  <p>My <code>App.js</code>:</p>
  <pre class="lang-js prettyprint-override"><code>import {BrowserRouter, Route} from &quot;react-router-dom&quot;;
  import Home from &quot;./Home&quot;;
  import Login from &quot;./Login&quot;;
  import {loggedIn, firebaseObserver} from &quot;../firebase&quot;;
  import {useEffect, useState} from &quot;react&quot;;
  
  export default function App() {
      const [authenticated, setAuthenticated] = useState(loggedIn())
  
      useEffect(() =&gt; {
          firebaseObserver.subscribe('authStateChanged', data =&gt; {
              setAuthenticated(data);
          });
          return () =&gt; { firebaseObserver.unsubscribe('authStateChanged'); }
      }, []);
  
     return &lt;BrowserRouter&gt;
               &lt;Route exact path=&quot;/&quot; render={() =&gt; (authenticated ? &lt;Home/&gt; : &lt;Login/&gt;)} /&gt;
            &lt;/BrowserRouter&gt;;
  }
  </code></pre>
  <p>My <code>firebase.js</code>:</p>
  <pre class="lang-js prettyprint-override"><code>import firebase from &quot;firebase/app&quot;;
  import &quot;firebase/auth&quot;;
  import &quot;firebase/firestore&quot;;
  import ReactObserver from 'react-event-observer';
  
  const firebaseConfig = {
      apiKey: ...,
      authDomain: ...,
      projectId: ...,
      storageBucket: ...,
      messagingSenderId: ...,
      appId: ...
  };
  firebase.initializeApp(firebaseConfig);
  export const auth = firebase.auth();
  export const firestore = firebase.firestore();
  export const firebaseObserver = ReactObserver();
  
  auth.onAuthStateChanged(function(user) {
      firebaseObserver.publish(&quot;authStateChanged&quot;, loggedIn())
  });
  
  export function loggedIn() {
      return !!auth.currentUser;
  }
  </code></pre>