Firebase authentication disappears on page refresh

Viewed 1693

I have a simple react app using firebase authentication. After successful Login the firebase:authUser is stored in localStorage. But on every page refresh localStorage is being cleared and the session is lost. Browsing through other pages doesn't clear localStorage though.

Here is what it looks like in code:

  1. Index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);

reportWebVitals();
  1. App.js
import { BrowserRouter as Router, Route, Routes } from "react-router-dom";
import Login from './Login';
import Main from './Main';
import Info from './Info';
import './App.css';

function App() {
  return (
    <div className="App">
        <Router>
          <Routes>
            <Route path="/login" element={<Login/>} />
            <Route path="/" element={<Main/>} />
            <Route path="/info" element={<Info/>} />
          </Routes>
        </Router>
    </div>
  );
}

export default App;

  1. Info.js → random page that I can view without authentication needed. Refreshing while on this page (http://localhost:3000/info) also clears localStorage
import { useNavigate } from "react-router-dom";

function Info() {

    const navigate = useNavigate();
        return (
            <div>
                <div>
                    Info page
                </div>
                <button
                    onClick={() => {
                            navigate('/');
                        }
                    }>
                        Go to Main
                </button>
            </div>
        );
}

export default Info;

Here is firebase.js I use to authenticate user

import { initializeApp } from 'firebase/app';
import { getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword, signOut, setPersistence, browserLocalPersistence } from 'firebase/auth';

const firebaseConfig = {
  // Here is my config
};

initializeApp(firebaseConfig);

// Auth
const auth = getAuth();
var email;
var password;

// Auth - set persistance
setPersistence(auth, browserLocalPersistence);

// Auth - create
createUserWithEmailAndPassword(auth, email, password)
  .then((userCredential) => {
    // Signed in 
    const user = userCredential.user;
  })
  .catch((error) => {
    const errorCode = error.code;
    const errorMessage = error.message;
  });

// Auth - Login
signInWithEmailAndPassword(auth, email, password)
  .then((userCredential) => {
    // Signed in 
    const user = userCredential.user;
  })
  .catch((error) => {
    const errorCode = error.code;
    const errorMessage = error.message;
  });

// Auth - signOut
signOut(auth).then(() => {
  // Sign-out successful.
}).catch((error) => {
  // An error happened.
});

export {
  auth,
  db,
  createUserWithEmailAndPassword,
  signInWithEmailAndPassword,
  signOut
};
1 Answers

In most browsers, when you reload the page, Firebase already restores the users authentication state from local storage by default. But since this requires it to call to the server, it may take a moment before it initialized the current user and you should use a so-called auth state listener as shown in the first code sample in the documentation on getting the current user:

import { getAuth, onAuthStateChanged } from "firebase/auth";

const auth = getAuth();
onAuthStateChanged(auth, (user) => {
  if (user) {
    // User is signed in, see docs for a list of available properties
    // https://firebase.google.com/docs/reference/js/firebase.User
    const uid = user.uid;
    // ...
  } else {
    // User is signed out
    // ...
  }
});

Your code only seems to handle the case where the user explicitly logs in, so it never picks up the restored user.


If the above works, check if you actually need the call to setPersistence(auth, browserLocalPersistence);. As said, on browsers this should already be the default behavior.

Related