Firebase:如何保持身份验证状态?

Firebase: How to persist auth state?

我正在使用没有 React 的 firebase web sdk。我的申请中有 4 页。我正在为每个页面使用 express js 来发送该路由的 html 文件。

我有一个名为 common.js 的文件,我在其中定义了将由所有页面共享的方法。在同一个文件中,我定义了一个方法来对 auth changed 进行操作,如下所示:

Modified below code

import { initializeApp } from 'firebase/app';
import { getAuth, onAuthStateChanged } from 'firebase/auth';
import { getFirestore } from 'firebase/firestore';
import { firebaseConfig } from './firebase.config';

const firebaseApp = initializeApp(firebaseConfig);
const db = getFirestore(firebaseApp);
const auth = getAuth(firebaseApp);

const addNavbar = () => {
   $('#nav').load('nav.html', () => {
      document.getElementById('btnSignOut').addEventListener('click', (e) => {
         auth.signOut();
      });
   });
}

// createAlert, createEditDeleteButtons, displayLoaderAndHideApp defined here

const unsubscribeOnAuthStateChanged = onAuthStateChanged(auth, async (user) => {
   if (user) {
      window.location.replace('/home');
   } else {
      window.location.replace('/login');
   }
});

export {
   addNavbar, auth, createAlert, createEditDeleteButtons, db, displayLoaderAndHideApp,
};

每个页面我先调用handleOnAuthStateChanged(),登录成功后也会调用。我想坚持认证所以我遇到了setPersistence(),所以我在login.js中使用它如下:

import { browserLocalPersistence, browserSessionPersistence, setPersistence, signInWithEmailAndPassword } from 'firebase/auth';
import { auth, handleOnAuthStateChanged } from './common';

document.getElementById('btnSignin').addEventListener('click', async (e) => {
   e.preventDefault();
   try {
      const form = document.querySelector('form.formLogin');
      const email = form.email.value.trim();
      const password = form.password.value;
      await setPersistence(auth, browserLocalPersistence);
      await signInWithEmailAndPassword(auth, email, password);
      handleOnAuthStateChanged(auth.currentUser); // here auth will retrieve the new logged in user
   } catch (e) {
      console.error(e);
   }
});

如果我在其他页面上使用 onAuthStateChanged() 我的用户为 null 那么我就会陷入循环。

我是不是漏掉了什么?

更新

所有最小代码都是在删除所有功能之后的,除了一些可能导致问题的功能。

我有一个名为 nav.html 的文件,它由 common.js 加载到页面中并且定义如上。

主页、第 1 页和第 2 页的代码通过调用 addNav 添加导航。 Home 会从common.js、page 2 的js 和page 1 的js 导入方法。首页js如下:

import { addDoc, collection, deleteDoc, doc, getDocs, onSnapshot, query, setDoc, where } from 'firebase/firestore';
import { addNavbar, createAlert, createEditDeleteButtons, db, displayLoaderAndHideApp as displayLoader } from './common';
// imports from page 1 and page 2

addNavbar();

// Other methods are defined here...

// Nothing is exported as of now..

Firebase 在大多数浏览器环境 上自动保留身份验证状态,并在 app/page 重新加载时恢复它。要检测身份验证状态的恢复(以及其他身份验证状态更改),您需要向 SDK 注册身份验证状态侦听器,如 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
    // ...
  }
});

您的 handleOnAuthStateChanged 的大部分代码都可能进入此处理程序。