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
的大部分代码都可能进入此处理程序。
我正在使用没有 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
的大部分代码都可能进入此处理程序。