import { createContext, useContext, useEffect, useMemo, useState, type PropsWithChildren, } from 'react'; import { onAuthStateChanged, type User as FirebaseAuthUser } from 'firebase/auth'; import { onSnapshot } from 'firebase/firestore'; import { auth } from '@/lib/firebase'; import { userDoc } from '@/lib/firestore'; import { registerForPushNotifications, subscribeToPushTokenRefresh, } from '@/services/notifications'; import type { UserDocument } from '@/types/firestore'; type AuthContextValue = { authUser: FirebaseAuthUser | null; user: UserDocument | null; initializing: boolean; }; const AuthContext = createContext(undefined); export function AuthProvider({ children }: PropsWithChildren) { const [authUser, setAuthUser] = useState(null); const [user, setUser] = useState(null); const [initializing, setInitializing] = useState(true); console.log("user is ", JSON.stringify(user)) useEffect(() => { let unsubscribeUserSnapshot: (() => void) | undefined; const unsubscribe = onAuthStateChanged(auth, (nextUser) => { setAuthUser(nextUser); if (unsubscribeUserSnapshot) { unsubscribeUserSnapshot(); unsubscribeUserSnapshot = undefined; } if (!nextUser) { setUser(null); setInitializing(false); return; } unsubscribeUserSnapshot = onSnapshot( userDoc(nextUser.uid), (snapshot) => { setUser(snapshot.data() ?? null); setInitializing(false); }, () => { setUser(null); setInitializing(false); } ); }); return () => { unsubscribe(); unsubscribeUserSnapshot?.(); }; }, []); useEffect(() => { if (!authUser) { return; } void registerForPushNotifications(authUser.uid); const unsubscribePushTokenRefresh = subscribeToPushTokenRefresh( authUser.uid ); return unsubscribePushTokenRefresh; }, [authUser]); const value = useMemo( () => ({ authUser, user, initializing, }), [authUser, initializing, user] ); return {children}; } export function useAuth() { const context = useContext(AuthContext); if (!context) { throw new Error('useAuth must be used within an AuthProvider'); } return context; }