首页 > 解决方案 > Firebase 身份验证。更新所有项目文件

问题描述

该项目由客户端firebase和vue开发。当用户登录成功时,我的 authService 在登录组件中更新。但是相同的对象没有在路由器中更新。authService 用于 Login 组件和 AdminNavbar 组件。在我看来,在每次登录和注销事件时,onAuthStateChanged 方法都会更新用户变量。这适用于登录组件,但不适用于路由器。出于这个原因,应用程序总是重定向到登录页面。

firebase 和 authService 端代码共享如下:

import firebase from 'firebase/app';
import 'firebase/auth';
import 'firebase/database';

const firebaseConfig = {
};

const firebaseApp = firebase.initializeApp(firebaseConfig);

const initializeAuth = new Promise(resolve => {
  firebase.auth().onAuthStateChanged(user => {
    authService.setUser(user);
    resolve(user);
    console.log(user); 
  })
})

const authService = {

  user: null,

  authenticated () {
    return initializeAuth.then(user => {
      return user && !user.isAnonymous
    })
  },

  setUser (user) {
    this.user = user
  },

  login (email, password) {
    firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION).then(function() {
      firebase.auth().signInWithEmailAndPassword(email, password)
    }).catch(function(error) {
      console.log(error);
    });
  },

  logout () {
    firebase.auth().signOut().then(() => {
      console.log('logout done')
    })
  }
}

export const db = firebaseApp.database();
export const hadithRef = db.ref('hadith');
export default authService;

路由器端代码共享如下:

import Vue from "vue";
import VueRouter from 'vue-router';

Vue.use(VueRouter);

// import components
import authService from './firebase.js';

const router = new VueRouter({
    mode: 'history',
    routes: [
      // this part is included path, name, components
    ]
});

router.beforeEach((to, from, next) => {
    // when user is login, user variable still is null. But same time user variable is not null in login component.
    // user is null at this point.
    console.log(authService.user);
    if (to.path == '/hadith/query' && authService.user == null) next({ path: '/login' })
    else if (to.path == '/hadith/add' && authService.user == null) next({ path: '/login' })
    else if (to.path == '/hadith/update' && authService.user == null) next({ path: '/login' })
    else next()
});

export default router;

main.js 代码共享如下:

import Vue from 'vue'
import '@babel/polyfill'
import 'mutationobserver-shim'
import './plugins/bootstrap-vue';
import './plugins/vuefire';

Vue.config.productionTip = false;

import App from './App.vue';
import router from './plugins/hrouter';

new Vue({
  render: h => h(App),
  router
}).$mount('#app')

标签: javascriptvue.jsfirebase-authenticationvue-router

解决方案


解决方案是这个链接。正如下面分享的,我们应该使用 vuex 并且它的状态设置在 onAuthStateChanged 观察者方法中。同时,我们坚持 vuex 的状态。你可以查看我的 github仓库

在您的 firebase 文件中修改 onAuthStateChanged 方法:

import store from '../store/index';
firebase.auth().onAuthStateChanged(function(user) {
  if (user) {
    store.dispatch('setUser', null);
  } else {
    store.dispatch('setUser', null);
  }
});

我们还为持久状态安装 vuex-persistedstate:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import createPersistedState from "vuex-persistedstate";
export default new Vuex.Store({
  plugins: [createPersistedState()],
  state: {
    user: null
  },
    getters:{
      getUser: state => {
          return state.user;
      }
    },
  mutations: {
    setUser(state, user){
      state.user = user;
    }
  },
  actions: {
    setUser(context, user){
        context.commit('setUser', user);
    },
  }
})

推荐阅读