如何在Vue2+Firebase9项目中搭配GoogleAuthProvider使用signInWithRedirect
原有代码存在的核心问题
- 执行逻辑断裂:
signInWithRedirect调用后会立即跳转至Google登录页,当前页面的JS执行上下文会完全销毁,你写在该方法后的getRedirectResult、结果处理、用户查询逻辑都不会执行,跳转回你的应用后也不会回到原函数的执行流程。 - 调用时机错误:
getRedirectResult不需要紧跟在signInWithRedirect之后调用,它的作用是在跳转回应用后的页面初始化阶段,获取之前的登录流程返回的认证结果,原代码的调用时机完全错误。 - 异常报错风险:移动端分支下页面跳转后原逻辑中断,
result变量不会被正常赋值,后续访问result.user会直接抛出undefined相关错误。
signInWithRedirect 正确实现方式
整体逻辑需要拆成两部分:登录触发逻辑 + 跳转回应用后的结果处理逻辑,你可以按照下面的方案修改:
1. 修正登录触发方法
移动端分支仅触发跳转即可,不需要编写后续处理逻辑:
googleSignIn: async function () { const auth = getAuth(); const provider = new GoogleAuthProvider(); try { let result; if (this.isMobile) { await signInWithRedirect(auth, provider); // 执行到这里时页面已经跳转,后续代码不会运行 } else { result = await signInWithPopup(auth, provider); // 桌面端流程不变,直接处理结果 await this.handleAuthResult(result) } } catch (err) { console.log(err); } }
2. 抽离公共认证结果处理方法
把原有的结果查询、状态更新、跳转逻辑抽离为公共方法,供桌面端和移动端跳转场景共用:
methods: { async handleAuthResult(result) { if (!result?.user) return const googleUser = result.user; const query = await db .collection("users") .where("email", "==", googleUser.email) .get(); if (!query.empty) { this.$store.dispatch("setUser", googleUser.reloadUserInfo); this.$router.push({ path: "/dashboard" }); } else { alert("impossible de se connecter"); } } }
3. 全局初始化时处理跳转结果
在根组件(比如App.vue)的created生命周期钩子中,调用getRedirectResult获取跳转登录的结果:
async created() { const auth = getAuth(); try { const result = await getRedirectResult(auth); // 存在跳转登录结果时才走处理逻辑 if (result) { await this.handleAuthResult(result) } } catch (err) { console.log('跳转登录异常:', err) } }
额外注意事项
- 确保调用
getRedirectResult前,Firebase Auth已经完成初始化,避免出现实例未定义的错误。 - 如果你的应用有路由守卫,也可以把跳转结果处理逻辑放在全局前置守卫中,时序会更可控。
- 可以额外增加状态判断,仅在移动端且当前用户未登录时调用
getRedirectResult,减少不必要的请求。
内容的提问来源于stack exchange,提问作者MVT KVM
相关产品推荐
相关产品推荐

