注册后Middleware跳转回登录页,刷新恢复正常问题求助
问题原因分析
你遇到的核心问题是注册完成后立即跳转时,用户状态还没完成更新,导致中间件判定用户未登录并跳转回登录页。具体细节:
createUserWithEmailAndPassword动作中,写完用户数据到数据库后直接调用$router.push,但此时Firebase的onAuthStateChanged回调以及后续获取完整用户资料的异步操作还没执行完毕,store.state.user仍处于初始的false或者临时的{ uid }状态(取决于回调触发时机)。- 中间件严格检测
store.state.user是否存在,一旦为false就跳转,而此时状态更新还没完成。 - 额外问题:
onAuthStateChangedAction中直接修改ctx.rootState.user = false不符合Vuex规范,应该通过mutation修改状态。
解决方案
方案一:注册完成后手动更新状态再跳转
修改createUserWithEmailAndPassword动作,在写入数据库后,手动触发用户资料获取并等待完成,再执行跳转:
async createUserWithEmailAndPassword({ dispatch, commit }, userData) { try { const result = await this.$fire.auth.createUserWithEmailAndPassword( userData.email, userData.password ) const user = result.user if (user) { // 写入用户数据到数据库 await this.$fire.database.ref(`users/${user.uid}`).update({ uid: user.uid, name: userData.name, photo: process.env.DEFAULT_PROFILE_PHOTO, phone: userData.phone, email: user.email, orders: '', coupons: '', bio: '' }) // 手动获取并更新用户资料,等待异步操作完成 await dispatch('getUserProfileFromDb', user.uid) // 使用Vuex上下文的router跳转,避免直接依赖$nuxt this.$router.push('/profile') } } catch (error) { console.log(error); } },
方案二:优化中间件的登录判定逻辑
如果希望保留依赖onAuthStateChanged回调的方式,可以修改中间件,允许用户状态为包含uid的临时对象(只要有uid就判定为已登录):
export default function ({ store, redirect }) { // 仅当user为false或空对象时,才跳转登录页 if (!store.state.user || (typeof store.state.user === 'object' && Object.keys(store.state.user).length === 0)) { redirect('/login') } }
额外修复:规范Vuex状态修改方式
修改onAuthStateChangedAction中直接修改rootState的错误,改用mutation:
onAuthStateChangedAction: async (ctx, { authUser, claims }) => { if (authUser) { await ctx.dispatch('getUserProfileFromDb', authUser.uid) } else { // 通过mutation设置user状态为false ctx.commit('setUserProfile', false) } },
可选优化:简化Firebase数据库读取方式
把getUserProfileFromDb中用axios的方式替换为Firebase SDK原生方法,更高效且不易出错:
async getUserProfileFromDb({ commit }, userUid) { try { const snapshot = await this.$fire.database.ref(`users/${userUid}`).once('value') const userProfile = snapshot.val() commit('setUserProfile', userProfile) } catch (error) { console.log(error) } },
内容的提问来源于stack exchange,提问作者Rustam Ravshanovich
相关产品推荐
相关产品推荐

