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

React集成Supabase Google认证时切换标签页后登出卡住问题求助

React集成Supabase Google认证时切换标签页后登出卡住问题求助

大家好,我已经被这个Google登出的问题困扰一周了😭:我的React应用里Google登录功能完全正常,但切换到其他标签页再切回来点击登出时,整个应用就卡住了。看日志发现,登出函数handleLogout里卡在了console.log("Supabase instance:", supabase);这一行,之后的代码都不执行了。

我用的是Supabase作为后端,集成了Google OAuth认证,完全是新手入坑认证流程,实在找不到问题出在哪,麻烦各位大佬帮忙看看!

我的代码(自定义Auth Hook)

import { useState, useEffect, useCallback } from "react";

// Custom hook for Google authentication and user management
export const useAuth = (supabase) => {
  const [user, setUser] = useState(null);
  const [isAuthenticating, setIsAuthenticating] = useState(false);

  // Handle user data upsert to database
  const upsertUserData = useCallback(
    async (sessionUser) => {
      if (!sessionUser) return;
      const userData = {
        id: sessionUser.id,
        email: sessionUser.email,
        created_at: sessionUser.created_at,
        last_login: new Date().toISOString(),
      };
      try {
        const { error } = await supabase.from("users").upsert(userData, {
          onConflict: "id",
        });
        if (error) {
          console.error("❌ Upsert error:", error);
        } else {
          console.log("✅ Upsert success");
        }
      } catch (error) {
        console.error("❌ Database error:", error);
      }
    },
    [supabase],
  );

  // Handle Google Sign-In
  const handleGoogleSignIn = useCallback(async () => {
    setIsAuthenticating(true);
    try {
      const { data, error } = await supabase.auth.signInWithOAuth({
        provider: "google",
        options: {
          redirectTo: `${window.location.origin}${window.location.pathname}`,
          queryParams: {
            access_type: "offline",
            prompt: "select_account",
          },
        },
      });
      console.log(redirectTo);
      if (error) {
        console.error("Google Sign-In error:", error);
        throw error;
      }
      return true;
    } catch (error) {
      console.error("Google Sign-In error:", error);
      alert(
        `Failed to sign in with Google: ${error.message}. Please try again.`,
      );
      return false;
    } finally {
      setIsAuthenticating(false);
    }
  }, [supabase]);

  // Handle logout
  const handleLogout = useCallback(async () => {
    console.log("Inside handleLogout function");
    try {
      console.log("Error");
      console.log("Supabase instance:", supabase);
      const { data, error: sessionError } = await supabase.auth.getSession();
      console.log("Session (rehydrated):", data?.session);
      // Force rehydration of session from storage (best workaround)
      //setUser(null);
      const { error } = await supabase.auth.signOut();
      console.log(error);
      //console.log("Error:", error);
      if (error) {
        console.error("Logout error:", error);
        alert("Failed to logout. Please try again.");
        return false;
      } else {
        console.log("✅ User logged out successfully");
        setUser(null);
        return true;
      }
    } catch (error) {
      console.error("Logout error:", error);
      alert("Failed to logout. Please try again.");
      return false;
    }
  }, [supabase]);

  // Check current authentication status
  const checkAuthStatus = useCallback(async () => {
    try {
      const { data: { user }, } = await supabase.auth.getUser();
      return user;
    } catch (error) {
      console.error("Auth check error:", error);
      return null;
    }
  }, [supabase]);

  // Set up auth state listener
  useEffect(() => {
    if (!supabase) return;
    const { data: { subscription }, } = supabase.auth.onAuthStateChange(async (event, session) => {
      console.log("Auth event:", event);
      if (event === "SIGNED_IN" && session?.user) {
        console.log("✅ User signed in:", session.user.email);
        await upsertUserData(session.user);
        setUser(session.user);
        setIsAuthenticating(false);
      }
      console.log("session user", session?.user || null);
      console.log("User event", event);
      if (event === "SIGNED_OUT") {
        console.log(event, "🚪 User signed out");
        setUser(null);
      }
    });

    // Check initial auth state
    const checkInitialAuth = async () => {
      const currentUser = await checkAuthStatus();
      if (currentUser) {
        setUser(currentUser);
      }
    };

    checkInitialAuth();

    return () => subscription.unsubscribe();
  }, [supabase, upsertUserData, checkAuthStatus]);

  return {
    user,
    setUser,
    isAuthenticating,
    setIsAuthenticating,
    handleGoogleSignIn,
    handleLogout,
    checkAuthStatus,
  };
};

我目前的排查

  • 登出函数卡在console.log("Supabase instance:", supabase);,后面的getSession()和signOut()都没执行
  • 只有切换标签页后才会出现这个问题,直接在当前页登出是正常的
  • 怀疑是Supabase实例在标签页切换后出现了状态异常?或者是session的存储同步有问题?

有没有大佬遇到过类似的情况,或者能帮我指出代码里的问题?感激不尽!

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 14:29:52