You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js 13中Firebase Google OAuth登录问题及刷新状态维持

Next.js 13 Firebase Google OAuth重定向登录问题及刷新维持状态方案

一、重定向登录后无法获取用户信息的问题原因

你的代码里有个关键错误:signInWithRedirect执行后会直接跳转到Google登录页,当前页面的代码会被中断,所以then、finally里的逻辑根本不会执行。等登录成功跳转回你的页面时,组件已经重新挂载,原来的回调上下文早就没了,自然拿不到结果。

二、解决方案

1. 修正重定向登录的逻辑

把获取重定向结果的逻辑放到组件挂载时的useEffect里,而不是登录点击事件中。当登录成功跳转回来后,组件重新渲染,此时调用getRedirectResult才能拿到正确的用户信息。

同时,handleGoogleSignIn只需要触发重定向即可,不需要额外的回调。

2. 维持刷新后的登录状态

Firebase Auth自带会话持久化机制,页面刷新时会自动恢复用户会话。我们只需要通过onAuthStateChanged监听用户状态变化,一旦检测到用户登录(包括刷新后恢复会话),就同步到你的AuthContext中。

三、修正后的完整代码

"use client";

import { useState, useEffect } from "react";
import { getAuth, GoogleAuthProvider, signInWithRedirect, getRedirectResult, onAuthStateChanged } from "firebase/auth";
import { app } from "../../firebase_config";
import { useAuth } from "./AuthContext";
import { FcGoogle } from "react-icons/fc";
import s from "./Login.module.css";

export default function Login() {
  const auth = getAuth(app);
  const provider = new GoogleAuthProvider();
  const [user, setUser] = useState(null);
  const { isLoggedIn, login, logout } = useAuth();

  // 处理重定向登录结果 + 监听用户状态变化(维持刷新登录状态)
  useEffect(() => {
    // 先尝试获取重定向登录的结果
    const fetchRedirectResult = async () => {
      try {
        const result = await getRedirectResult(auth);
        if (result) {
          const user = result.user;
          setUser(user);
          login();
        }
      } catch (error) {
        console.error("获取重定向结果失败:", error);
      }
    };

    fetchRedirectResult();

    // 监听用户状态变化,处理刷新页面后的会话恢复
    const unsubscribe = onAuthStateChanged(auth, (currentUser) => {
      if (currentUser) {
        setUser(currentUser);
        login();
      } else {
        setUser(null);
        // 这里可以根据需求调用logout或者不处理
      }
    });

    // 组件卸载时取消监听
    return () => unsubscribe();
  }, [auth, login]);

  const handleGoogleSignIn = () => {
    // 只需要触发重定向,跳转后当前页面代码会终止
    signInWithRedirect(auth, provider);
  };

  return (
    <div>
      {isLoggedIn && user ? (
        <div className={s.userProfile}>
          <img className={s.userImg} src={user.photoURL} alt="用户头像" />
          <span>{user.displayName}</span>
        </div>
      ) : (
        <button onClick={handleGoogleSignIn}>
          <FcGoogle style={{ fontSize: "1.2em" }} />
          登录
        </button>
      )}
    </div>
  );
}

关键改动说明

  • 移除了handleGoogleSignIn中的then和finally回调,因为重定向后这些代码不会执行。
  • 在useEffect中添加了getRedirectResult的调用,确保跳转回页面后能获取登录结果。
  • 新增onAuthStateChanged监听,页面刷新时Firebase会自动恢复会话,这个监听会捕获到用户状态,从而同步到组件和AuthContext中,维持登录状态。
  • 给img标签添加了alt属性,符合HTML规范。

内容的提问来源于stack exchange,提问作者하고타

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 01:33:35