Javascript 如何在单页应用程序(SPA)中正确配置Firebase Auth?

Javascript 如何在单页应用程序(SPA)中正确配置Firebase Auth?,javascript,firebase,routes,firebase-authentication,single-page-application,Javascript,Firebase,Routes,Firebase Authentication,Single Page Application,我很难理解如何在SPA web应用程序中最好地实现Firebase Auth。我对温泉和火炉都是新手 我的应用程序由安全页面和非安全页面组成。非安全页面用于条款和条件、隐私政策和忘记密码等内容 在我的应用程序代码中,在最高级别,例如/app.js,我将导入Firebase Auth配置模块作为第一个操作顺序。此模块包含以下函数,用于侦听身份验证中的更改并相应地执行操作 firebase.auth().onAuthStateChanged(user => { if (!user) {

我很难理解如何在SPA web应用程序中最好地实现Firebase Auth。我对温泉和火炉都是新手

我的应用程序由安全页面和非安全页面组成。非安全页面用于条款和条件、隐私政策和忘记密码等内容

在我的应用程序代码中,在最高级别,例如
/app.js
,我将导入Firebase Auth配置模块作为第一个操作顺序。此模块包含以下函数,用于侦听身份验证中的更改并相应地执行操作

firebase.auth().onAuthStateChanged(user => {
    if (!user) {
        Store.router.navigate("/login"); // <-- this is my problem
    } else {
        // get user data from Cloud Firestore
        // store user data locally
    }
});
在我决定使用Firebase Auth之前,我的路由器检查了每条路由的身份验证,看起来有点像这样:

router.on({
    '/': () => {
        if (isAuthenticated) {
            // import module
        } else {
           router.navigate("/login")
        }
    },
    '/login': () => {
        if (!isAuthenticated) {
            // import module
        } else {
           router.navigate("/")
        }
    },
    '/forgot-password': () => {
        // import module
    }
}).resolve();
每次使用Firebase Auth版本的my app更改路由时,
onAuthStateChanged
侦听器都会收到一个更新,如果用户注销,它会将他们重定向到
/login
页面。如果登录,它会从数据库中获取用户的完整配置文件并将其存储在本地

现在,除非用户已注销,在
/login
页面上,并且想要访问
/forget password
页面,否则此操作将非常有效。当用户导航到此页面或任何其他不安全的公共页面时,身份验证侦听器会立即更新自身并将用户重定向回
/login
,这是错误的

这是非常不受欢迎的,但我真的很喜欢这个监听器的工作方式,就像/当用户打开多个选项卡并从其中一个中注销时,它会将所有选项卡返回到
/login


如何配置此侦听器或重新配置我的应用程序以允许公共页面也可用?我应该取消听众的订阅吗?

我设法解决了这个问题,所以我将在这里为其他人分享我的发现。然而,我确实丢失了当他们注销一个标签页时将所有打开的标签页返回到登录页的功能,但这对于我的应用程序来说效果更好,因为它有公共路由

我现在在我的用户模块中有一个名为
getCurrentUser()
的方法,它现在是
onAuthStateChanged
observable所在的位置。因为我使用了“unsubscribe()”方法,所以我现在可以在需要时调用它,而无需不断观察它

getCurrentUser: () => {
    return new Promise((resolve, reject) => {
        const unsubscribe = firebase.auth().onAuthStateChanged(user => {
            unsubscribe();
            resolve(user);
        }, reject);
    })
}
在我的路由器中,我现在可以通过调用并等待
User.getCurrentMethod()
来检查身份验证状态


这听起来像是逻辑错误。您可以在onAuthStateChanged上查看您的路由是什么,如果是公共路由,则什么也不做。问题是您试图在身份验证状态更改中导航。最好的方法是仅当用户尝试导航到不同的页面/分区时才这样做。
getCurrentUser: () => {
    return new Promise((resolve, reject) => {
        const unsubscribe = firebase.auth().onAuthStateChanged(user => {
            unsubscribe();
            resolve(user);
        }, reject);
    })
}
router.on({
    '/': async () => {
        if (await User.getCurrentUser()) {
            // import module
            // load HTML
        } else {
            router.navigate('/login')
        }
    },
    '/login': () => {
        ...
    }