Firebase+GraphQL谷歌认证登录偶现Apollo Client错误求助
Firebase+GraphQL+MongoDB认证系统登录偶发Apollo Client错误排查
我基于Firebase、GraphQL与MongoDB搭建了认证系统,注册功能正常,但登录操作有时成功,有时会触发Apollo Client错误,无法确定问题原因。以下是相关代码及报错截图:
认证逻辑代码
import { FirebaseAuth } from "../config/Firebase"; import { GoogleAuthProvider, signInWithPopup } from "firebase/auth"; import { Notifier } from "../utils"; import { USER_AUTH_ERROR } from "../config/Responders"; const Google = async (Register, Login, dispatch) => { var Provider = new GoogleAuthProvider(); const data = await signInWithPopup(FirebaseAuth, Provider); try { if (data) { const user = data.user; const creationTime = user.metadata.creationTime; const lastSignInTime = user.metadata.lastSignInTime; if (creationTime === lastSignInTime) { const name = user.displayName.split(" "); const firstName = name[0] || ""; const lastName = name[1] || ""; const config = { variables: { createUserInput: { Name: firstName, Surname: lastName, Email: user.email, Avatar: user.photoURL || null, Uid: user.uid, }, }, }; Register(config); } else { const config = { variables: { uid: user.uid, }, }; Login(config); } } else Notifier(dispatch, USER_AUTH_ERROR, `error`); } catch (error) { Notifier(dispatch, USER_AUTH_ERROR, `error`); } }; export default Google;
函数管理代码
const [Register, { data: registerData }] = useMutation(REGISTER); const [Login, { data: loginData }] = useLazyQuery(AUTH); const Auther = () => Google(Register, Login, dispatch); useEffect(() => { if (!account.Auth) { if (registerData?.hasOwnProperty("UserRegister")) { dispatch(Authenticate(registerData.UserRegister)); } } }, [registerData]); useEffect(() => { if (!account.Auth) { if (loginData?.hasOwnProperty("UserAuth")) { dispatch(Authenticate(loginData.UserAuth)); } } }, [loginData]);
报错截图

问题排查与修复建议
修正错误捕获范围
当前signInWithPopup未被包裹在try/catch中,若授权弹窗出现异常(比如用户中途关闭),会直接抛出未捕获错误,导致后续逻辑中断。调整代码:const Google = async (Register, Login, dispatch) => { var Provider = new GoogleAuthProvider(); try { const data = await signInWithPopup(FirebaseAuth, Provider); if (data) { // 原有用户判断逻辑 } else { Notifier(dispatch, USER_AUTH_ERROR, `error`); } } catch (error) { console.error("Firebase授权错误:", error); Notifier(dispatch, USER_AUTH_ERROR, `error`); } };添加GraphQL查询错误处理
useLazyQuery调用后未处理错误状态,查询失败时错误会被Apollo Client直接抛出。补充错误监听:const [Login, { data: loginData, error: loginError }] = useLazyQuery(AUTH); useEffect(() => { if (loginError) { console.error("登录查询错误:", loginError); Notifier(dispatch, USER_AUTH_ERROR, `error`); } }, [loginError]);优化时间戳比较逻辑
Firebase的creationTime与lastSignInTime可能存在毫秒级差异或时区格式问题,直接全等判断会导致逻辑分支错误。改为数值比较并允许误差:const creationTimestamp = new Date(creationTime).getTime(); const lastSignInTimestamp = new Date(lastSignInTime).getTime(); // 允许1秒内的误差,避免首次登录时的时间差问题 if (Math.abs(creationTimestamp - lastSignInTimestamp) < 1000) { // 注册逻辑 } else { // 登录逻辑 }避免重复触发状态更新
原useEffect未监听account.Auth的变化,可能导致重复触发dispatch。调整依赖项:useEffect(() => { if (!account.Auth && registerData?.UserRegister) { dispatch(Authenticate(registerData.UserRegister)); } }, [registerData, account.Auth, dispatch]); useEffect(() => { if (!account.Auth && loginData?.UserAuth) { dispatch(Authenticate(loginData.UserAuth)); } }, [loginData, account.Auth, dispatch]);
此外,建议启用Apollo Client开发者工具,查看具体的GraphQL请求/响应细节,确认是参数错误、服务器返回异常还是缓存冲突导致的偶发问题。
内容的提问来源于stack exchange,提问作者nevoni3008
相关产品推荐
相关产品推荐

