Firebase身份验证状态更改后初始化Vue应用

Ale*_*lex 9 firebase vue.js firebase-authentication vuex vuejs2

我的Vue / vuex / vue-router + Firebase应用程序中有一个难题。引导程序代码应初始化Firebase以及Vuex中已登录的用户(如果有):

new Vue({
  el: '#app', router, store, template: '<App/>', components: { App },
  beforeCreate() {
    firebase.initializeApp(firebaseConfig)
      // Because the code below is async, the app gets created before user is returned...
      .auth().onAuthStateChanged(user => {
        this.$store.commit('syncAuthUser', user) // this executes too late...
      })
  }
})
Run Code Online (Sandbox Code Playgroud)

在我的路线中,我有

{ path: '/home', name: 'Home', component: Home, meta: { requiresAuth: true } }
Run Code Online (Sandbox Code Playgroud)

以及

router.beforeEach((to, from, next) => {
  let authUser = store.getters.authUser // this is not set just yet...

  if (to.matched.some(record => record.meta.requiresAuth)) {
    if (!authUser) {
      next('signin') // /home will always hit here...
    }
    next()
  }
  else {
    next()
  }
})
Run Code Online (Sandbox Code Playgroud)

问题

如评论中所述,该应用获取身份验证的用户为时已晚。所以,当你去/home,同时登录,应用程序将运行beforeEach在线路检查......而用户实例将不可用,只是还没有,所以它会认为你还没有登录,而事实上你是(很明显,根据我的计算属性,稍后会对其进行正确更新)。

因此,如何更改我的代码,以便仅在Firebase返回用户并将该用户传递到Vuex存储后才初始化Vue应用程序?请让我知道我做错了什么。

尝试次数

  1. 我尝试了“退订”方法;但是,它的问题是onAuthStateChanged只会触发一次。因此,如果我把关键放在this.$store.commit('syncAuthUser', user)这里,那么该代码将仅在创建应用程序时执行,而不是在用户注销时执行。
  2. 我也在这里尝试了一种更好的方法。我确实为我工作,但我感到自己换onAuthStateChanged了另一套书就不好了Promise,肯定有更好的方法了。另外,将auth用户初始化登录名放置在路由文件中似乎是错误的。

Cha*_*add 1

例子

./App.vue

created: function() {
  auth.onAuthStateChanged(user => {

    this.$store.dispatch("SET_USER", user)

    user.getIdToken().then( token => {
      this.$store.dispatch("SET_TOKEN", token)
    })
}
Run Code Online (Sandbox Code Playgroud)

./store.js(突变)

export default {
  SET_USER(state, user) {
    state.authenticated = !!user
    state.user = {
      email: user ? user.email : null,
      displayName: user ? user.displayName : null,
      photoURL: user ? user.photoURL : null,
    }
  }
  SET_TOKEN(state, payload) {
    state.token = payload
  }
}
Run Code Online (Sandbox Code Playgroud)

概述

生命周期

此示例使用 Vue 的生命周期挂钩运行created:。在内部created:我们用来auth.onAuthStateChanged启动一个事件监听器。您的应用程序现在正在侦听来自 firebase 的身份验证更改。

auth.onAuthStateChanged(user => { ...listening for user objects... })
Run Code Online (Sandbox Code Playgroud)

user每当 Firebase 注意到身份验证状态更改时,就会返回该对象。使用其属性方法进行身份验证和授权。

财产: user.emailVerfied

方法: user.getIdToken()

长话短说

使用 Firebase 时onAuthStateChanged,您必须实现ObservableSubscriptions对象。RxJS Observable 像 a 一样是异步的promise,它将帮助您等待来自 Firebase 的身份验证响应。

请参阅文档中的第一个参数:nextOrObserver

onAuthStateChanged(nextOrObserver, error, completed) returns function()
Run Code Online (Sandbox Code Playgroud)

Observable设计模式(即异步、推送、多播)记录在此处