Fix: Resolve stale state issue in auth profile fetching

This commit is contained in:
gpt-engineer-app[bot]
2025-10-13 17:17:02 +00:00
parent 5863a49d3a
commit be26c08640

View File

@@ -32,9 +32,11 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) {
const isMountedRef = useRef(true); const isMountedRef = useRef(true);
const profileFetchTimeoutRef = useRef<NodeJS.Timeout | null>(null); const profileFetchTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const novuUpdateTimeoutRef = useRef<NodeJS.Timeout | null>(null); const novuUpdateTimeoutRef = useRef<NodeJS.Timeout | null>(null);
const fetchedUserIdRef = useRef<string | null>(null);
const previousEmailRef = useRef<string | null>(null); const previousEmailRef = useRef<string | null>(null);
const fetchProfile = async (userId: string) => { const fetchProfile = async (userId: string) => {
console.log('[Auth] 📡 fetchProfile called for userId:', userId);
try { try {
const { data, error } = await supabase const { data, error } = await supabase
.from('profiles') .from('profiles')
@@ -42,24 +44,29 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) {
.eq('user_id', userId) .eq('user_id', userId)
.maybeSingle(); .maybeSingle();
console.log('[Auth] 📦 Profile fetch result:', {
hasData: !!data,
hasError: !!error,
avatar_url: data?.avatar_url
});
if (error && error.code !== 'PGRST116') { if (error && error.code !== 'PGRST116') {
authError('[Auth] Error fetching profile:', error); authError('[Auth] Error fetching profile:', error);
// Don't clear profile on error - keep existing data
return; return;
} }
if (isMountedRef.current && data) { if (isMountedRef.current && data) {
console.log('[Auth] ✅ Profile loaded:', { console.log('[Auth] ✅ Setting profile state with data:', {
userId: data.user_id, userId: data.user_id,
username: data.username, username: data.username,
avatar_url: data.avatar_url, avatar_url: data.avatar_url,
hasData: !!data
}); });
setProfile(data as Profile); setProfile(data as Profile);
} else {
console.log('[Auth] ⚠️ NOT setting profile - mounted:', isMountedRef.current, 'hasData:', !!data);
} }
} catch (error) { } catch (error) {
authError('[Auth] Error fetching profile:', error); authError('[Auth] ❌ Exception in fetchProfile:', error);
// Don't clear profile on error - keep existing data
} }
}; };
@@ -141,6 +148,8 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) {
} }
} else if (event === 'SIGNED_OUT') { } else if (event === 'SIGNED_OUT') {
authLog('[Auth] SIGNED_OUT - clearing state'); authLog('[Auth] SIGNED_OUT - clearing state');
console.log('[Auth] 🔴 SIGNED_OUT - clearing profile and fetch tracking');
fetchedUserIdRef.current = null;
setSession(null); setSession(null);
setUser(null); setUser(null);
setProfile(null); setProfile(null);
@@ -216,18 +225,21 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) {
// Handle profile fetching for authenticated users (async, doesn't block loading) // Handle profile fetching for authenticated users (async, doesn't block loading)
if (session?.user) { if (session?.user) {
// Only fetch if we don't have a profile or user ID changed // Only fetch if we haven't fetched for this user yet
if (!profile || profile.user_id !== session.user.id) { if (fetchedUserIdRef.current !== session.user.id) {
console.log('[Auth] 🔄 Fetching profile for user:', session.user.id);
fetchedUserIdRef.current = session.user.id;
if (profileFetchTimeoutRef.current) { if (profileFetchTimeoutRef.current) {
clearTimeout(profileFetchTimeoutRef.current); clearTimeout(profileFetchTimeoutRef.current);
profileFetchTimeoutRef.current = null; profileFetchTimeoutRef.current = null;
} }
// Call directly - fetchProfile is already async
fetchProfile(session.user.id); fetchProfile(session.user.id);
} else {
console.log('[Auth] ✅ Profile already fetched for user:', session.user.id);
} }
} }
// Profile is already cleared in SIGNED_OUT handler above
}); });
// THEN get initial session (this may trigger INITIAL_SESSION event) // THEN get initial session (this may trigger INITIAL_SESSION event)
@@ -247,6 +259,7 @@ function AuthProviderComponent({ children }: { children: React.ReactNode }) {
return () => { return () => {
authLog('[Auth] Cleaning up auth provider'); authLog('[Auth] Cleaning up auth provider');
isMountedRef.current = false; isMountedRef.current = false;
fetchedUserIdRef.current = null;
subscription.unsubscribe(); subscription.unsubscribe();
// Clear any pending timeouts // Clear any pending timeouts