带有firebase身份验证的vue路由器错误
Posted
技术标签:
【中文标题】带有firebase身份验证的vue路由器错误【英文标题】:vue router error with firebase auth 【发布时间】:2018-04-13 09:13:09 【问题描述】:我尝试使用 vue.js 和 firebase 进行身份验证。
并且发生错误 router.beforeEach 函数, 有人知道为什么会发生这种情况吗?
控制台错误
vue-router.esm.js?fe87:16 [vue-router] 路由导航期间未捕获的错误: 警告@ vue-router.esm.js?fe87:16 中止@vue-router.esm.js?fe87:1904 迭代器@vue-router.esm.js?fe87:1968 步@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 推@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>
登录.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】:确保在通过导航守卫的任何给定传递中,下一个函数只被调用一次。它可以出现多次,但前提是逻辑路径没有重叠,否则钩子永远不会被解析或产生错误。
你的 else if 条件 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
希望这会有所帮助。
【讨论】:
以上是关于带有firebase身份验证的vue路由器错误的主要内容,如果未能解决你的问题,请参考以下文章
必须点击登录按钮两次;使用 vue-router 和 firebase 身份验证
如果用户已经使用 Vue 和 Firebase 身份验证登录,如何自动重定向用户?