最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Firebase authentication disappears on page refresh - Stack Overflow

programmeradmin5浏览0评论

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
};

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
};
Share Improve this question edited Nov 7, 2021 at 15:51 Frank van Puffelen 601k85 gold badges890 silver badges860 bronze badges Recognized by Google Cloud Collective asked Nov 7, 2021 at 8:45 kenkechkenkech 731 silver badge5 bronze badges 2
  • Are you sure it's not your browser configuration? Try changing your browser – Nestor Solalinde Commented Nov 7, 2021 at 9:04
  • @NestorSolalinde I have tried chrome & safari. Both act the same. Also I have tried to use SessionStorage instead of local and it has the same effect → on refresh firebase:authUser just disappears – kenkech Commented Nov 7, 2021 at 9:53
Add a ment  | 

2 Answers 2

Reset to default 4

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./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.

Some times the onAuthStateChanged method don't solve the problem. At least in my case. Doug Stevenson wrote a blog about the "Why is my currentUser == null in Firebase Auth?".(link).

First of all the current user not binary it is actually trinary:

  1. unknown (still not read)
  2. sing in %100
  3. sing out %100

so you need to consider there cases handle individually. He has his own example implementation in the his blog post so I will my solution here.

  const [user, setUser] = useState<User | null | undefined>(undefined);

I defined my user with 3 possible values so I can handle each cases. user object enitial value is null so it is the unknown case

auth.onAuthStateChanged(function (firebaseUser) {
  if (firebaseUser) {
    setUser(firebaseUser);
  } else {
    setUser(null);
  }
});

If the user is signed out %100 the the value is null.

In my auth provider I checked all there cases

  if (user == undefined) {
    return <h1>loading...</h1>;
  } else if (!user) {
    return <Navigate to={"/login"} />;
  }
    return <what ever you content is />;
发布评论

评论列表(0)

  1. 暂无评论