Firebase onAuthStateChanged 和 Navigation Guards 的模式 - Quasar 应用
Posted
技术标签:
【中文标题】Firebase onAuthStateChanged 和 Navigation Guards 的模式 - Quasar 应用【英文标题】:Pattern for Firebase onAuthStateChanged and Navigation Guards - Quasar app 【发布时间】:2018-10-23 17:44:40 【问题描述】:我的 Quasar 应用程序在浏览器刷新和 Firebase 身份验证方面遇到问题。
在用户登录并单击浏览器刷新后,firebase.auth().currentUser
返回 null(因为它是异步执行的)。这意味着当beforeEach
被执行时,currentUser
为空并且用户被提示登录页面。但是我看到,当调用onAuthStateChanged
的回调时,用户设置正确。
在 Quasar 应用程序中,是否有任何模式可以在导航过程中使用 onAuthStateChanged
,以便重复使用现有的用户会话?
// Vue-router => index.js
firebase.auth().onAuthStateChanged(user =>
console.log('onAuthStateChanged Invoked => ' + user);
);
router.beforeEach((to, from, next) =>
let currentUser = firebase.auth().currentUser;
let requiresAuth = to.matched.some(record => record.meta.requiresAuth);
if (requiresAuth && !currentUser)
next('signin');
else
if (requiresAuth && currentUser.emailVerified === false)
next('signin');
else
next();
);
【问题讨论】:
【参考方案1】:在您的main.js
中,您应该收听onAuthStateChange
。
import Vue from 'vue'
import App from './App'
import router from './router'
import firebase from 'firebase'
Vue.config.productionTip = false
let app;
let config =
apiKey: "YOUR_API_KEY",
authDomain: "YOUR_PROJECT_ID.firebaseapp.com",
databaseURL: "https://YOUR_PROJECT_ID.firebaseio.com",
projectId: "YOUR_PROJECT_ID",
storageBucket: "YOUR_PROJECT_ID.appspot.com",
messagingSenderId: "YOUR_MESSAGING_SEND_ID"
;
firebase.initializeApp(config)
firebase.auth().onAuthStateChanged(function(user)
if (!app)
/* eslint-disable no-new */
app = new Vue(
el: '#app',
template: '<App/>',
components: App ,
router
)
);
只有在确定 Firebase Auth 对象可以使用时,我们才会初始化应用程序。
【讨论】:
谢谢。我之前看过这个提议。然而,对于 Quasar 应用程序,初始化似乎是由框架完成的。我遇到了一个解决方案(在 VueJS 论坛 - forum.vuejs.org/t/vue-routes-firebase-auth-sync-problem/4470)用 Promise 包装firebase.auth().currentUser
,然后使用 promise 解析来执行 beforeEach
中的逻辑,这似乎是有效的。
同样的代码只是放在 Quasar 启动文件中。【参考方案2】:
我直接在路由器保护中使用 firebase.auth().onAuthStateChanged 函数,如下所示: 我检查路由是否需要经过身份验证的用户(可选),然后加载当前登录的用户并将其提交到我的 Vuex 存储中。 这样,在路由保护检查访问之前,当前登录的用户就处于我的 Vuex 状态。否则,尤其是在页面重新加载后,用户尚未加载,守卫重定向到登录页面...
...
Router.beforeEach((to, from, next) =>
let requiresAuth = to.matched.some(record => record.meta.requiresAuth)
// If route requires auth --> load auth state first from firebase
if (requiresAuth)
firebase.auth().onAuthStateChanged(user =>
store.commit("user/SET_USER", user);
let currentUser = firebase.auth().currentUser
store.commit("user/SET_USER_FULL", currentUser);
user.getIdToken().then(token =>
store.commit("user/SET_TOKEN", token)
);
if (!user) next('login')
else next();
);
else next()
)
export default Router
我使用类星体。这段代码在我的路由器/index.js 中。不要忘记像这样导入您的商店:import store from '../store'
【讨论】:
以上是关于Firebase onAuthStateChanged 和 Navigation Guards 的模式 - Quasar 应用的主要内容,如果未能解决你的问题,请参考以下文章
firebase.auth().onAuthStateChanged 不工作
如何从 firebase.auth().onAuthStateChanged 中提取数据
.onAuthStateChanged 方法是不是计入 Firebase 身份验证验证?
TypeError: firebase.auth(...).onAuthStateChanged 不是函数