使用firebase身份验证的vue路由器错误

时间:2017-11-01 04:35:26

标签: firebase authentication vue.js vue-router

我尝试使用vue.js和firebase进行身份验证。

并且发生错误router.beforeEach函数, 任何人都知道为什么会发生这种情况?

控制台错误

  路由导航期间

vue-router.esm.js?fe87:16 [vue-router]未捕获错误:
  警告@ vue-router.esm.js?fe87:16
  abort @ vue-router.esm.js?fe87:1904
  iterator @ vue-router.esm.js?fe87:1968
  step @ vue-router.esm.js?fe87:1717
  runQueue @ vue-router.esm.js?fe87:1725
  confirmTransition @ vue-router.esm.js?fe87:1972
  transitionTo @ vue-router.esm.js?fe87:1874
  push @ vue-router.esm.js?fe87:2181
  (匿名)@ vue-router.esm.js?fe87:1960
  (匿名)@ index.js?3672:44

路由器/ index.js

import Vue from 'vue'
import Router from 'vue-router'
import addPost from '@/components/addPost'
import showPost from '@/components/showPost'
import Login from '@/components/Login'
import SignUp from '@/components/SignUp'
import firebase from 'firebase'


Vue.use(Router)

const router = new Router({
    mode: 'history',
  routes: [
    {
      path: '/',
      name: 'app',
      component: showPost
    },
    {
      path: '/add',
      component: addPost,
      meta: {
        requiresAuth: true
      }
    },
    {
        path: '/login',
        name: 'Login',
        component: Login
    },
    {
        path: '/signup',
        name: 'SignUp',
        component: SignUp
    }
  ]
})

router.beforeEach((to, from, next) => {
  let currentUser = firebase.auth().currentUser;
  let requiresAuth = to.matched.some(record => record.meta.requiresAuth);

  if (requiresAuth && !currentUser) next('/login')
  else if (!requiresAuth && currentUser) next('/')
  else next()
})


export default router

main.js

import Vue from 'vue'
import App from './App'
import router from './router'
import VueFire from 'vuefire'
import firebase from 'firebase'

Vue.use(VueFire)

Vue.config.productionTip = false

let app;

firebase.auth().onAuthStateChanged(function(user) {

    if(!app) {
        app = new Vue({
          el: '#app',
          router,
          template: '<App/>',
          components: { App }
        })
    }

})

App.vue

<template>
  <div id="app">
    <app-header></app-header>
    <router-view></router-view>
    <button @click="logout">Logout</button>
  </div>
</template>

<script>
import header from './components/header'
import firebase from 'firebase'

export default {
  name: 'app',
  components: {
     'app-header': header
  },
  methods: {
    logout: function() {
      firebase.auth().signOut().then(() => {
        this.$router.replace('login')
      })
    }
  }
}

</script>

Login.vue

import firebase from 'firebase'

import db from '../firebaseInit'
const postRef = db.ref('posts')

export default {
  name: 'login',
  data: function() {
    return {
      email: '',
      password: ''
    }
  },
  methods: {
    signIn: function() {
      firebase.auth().signInWithEmailAndPassword(this.email, this.password).then(
        (user) => {
          this.$router.replace('/')
        },
        (err) => {
          alert('Oops ' + err.message)
        }
      );
    }
  }
}
</script>

addPost.vue

<template>
  <div id="add-blog">
      <h2>Add a New Post</h2>
      <form v-if="!submitted">
        <label>Title:</label>
        <input type="text" v-model="newPost.title" required />
        <p>{{ getDate }}</p>
        <label for="">Content:</label>
        <textarea v-model.trim="newPost.content"></textarea>
        <div id="checkboxes">
          <p>Categories:</p>
          <label>Vue.js</label>
          <input type="checkbox" value="vue" v-model="newPost.categories" />
          <label>CSS Magic</label>
          <input type="checkbox" value="css" v-model="newPost.categories" />
        </div>
        <label>Author:</label>
        <select v-model="newPost.author">
          <option v-for="author in authors">{{ author }}</option>
        </select>
        <button @click.prevent="addPost">Add Post</button>
      </form>
      <div v-if="submitted">
        <p>Congraturation!</p>
      </div>
      <div id="preview">
        <h3>Preview Post</h3>
        <h4>Title {{ newPost.title }}</h4>
        <h4>Content </h4>
        <p style="white-space: pre">{{ newPost.content }}</p>
        <ul>
          <li v-for="category in newPost.categories">{{ category }}</li>
        </ul>
        <p>{{ newPost.author }}</p>
      </div>
    </div>
</template>

<script>

import db from '../firebaseInit'
const postRef = db.ref('posts')

export default {
  data() {
    return {
      newPost: {
        date: '',
        title: '',
        author: '',
        content: '',
        categories: []
      },
      authors: ['Naeun', 'Raphael'],
      submitted: false,
      items: []
    }
  },
  methods: {
    addPost: function() {
      postRef.push(this.newPost)
      this.newPost.date = '',
      this.newPost.title = '',
      this.newPost.author = '',
      this.newPost.content = '',
      this.newPost.categories = ''
    },
    removePost: function() {
      postRef.child(post['.key']).remove()
    }
  },
  computed: {
    getDate: function() {
      const toTwoDigits = num => num < 10 ? '0' + num : num;
      let today = new Date();
      let year = today.getFullYear();
      let month = toTwoDigits(today.getMonth() + 1);
      let day = toTwoDigits(today.getDate());
      return this.newPost.date = `${year}-${month}-${day}`;
    }
  }
}

</script>

1 个答案:

答案 0 :(得分:0)

确保在任何给定的通过导航保护的过程中,将仅一次调用下一个函数。它可以出现多次,但前提是逻辑路径没有重叠,否则挂钩将永远无法解决或产生错误。

如果条件else if (!requiresAuth && currentUser) next('/')违反了此规则,则其他情况。

更改路由防护逻辑

// check if route requiresAuth
router.beforeEach((to, from, next) => {
  if (to.matched.some(rec => rec.meta.requiresAuth)) {
    const user = firebase.auth().currentUser;
    // check auth state of user
    user ? next() : next('/login') // user not signed in, route to login
  } else {
    next(); // route does not require auth
  }
});

https://router.vuejs.org/guide/advanced/navigation-guards.html#global-before-guards

希望这会有所帮助。