1- import React , { createContext , ReactNode , useCallback , useContext , useEffect , useState } from 'react' ;
2- import { GoogleAuthProvider , OAuthProvider , onAuthStateChanged , signInWithCredential , signInWithPopup } from 'firebase/auth' ;
1+ import React , { createContext , ReactNode , useCallback , useContext , useState } from 'react' ;
2+ import { GoogleAuthProvider , OAuthProvider , signInWithCredential , signInWithPopup } from 'firebase/auth' ;
33import { auth } from '../config/firebase' ;
44import { getUserFromFirestore , User } from '../services/userService' ;
55
66interface AuthContextType {
77 user : User | null ;
88 isLoading : boolean ;
9- isInitialized : boolean ;
109 loadUserState : ( ) => Promise < void > ;
1110 login : ( credential : string , provider ?: 'google' | 'apple' ) => Promise < void > ;
1211 loginWithApple : ( ) => Promise < void > ;
@@ -24,74 +23,32 @@ interface AuthProviderProps {
2423export const AuthProvider : React . FC < AuthProviderProps > = ( { children} ) => {
2524 const [ user , setUser ] = useState < User | null > ( null ) ;
2625 const [ isLoading , setIsLoading ] = useState ( false ) ;
27- const [ isInitialized , setIsInitialized ] = useState ( false ) ;
28- const [ userCache , setUserCache ] = useState < Map < string , { user : User ; timestamp : number } > > ( new Map ( ) ) ;
29-
30- // Cache timeout: 5 minutes
31- const CACHE_TIMEOUT = 5 * 60 * 1000 ;
32-
33- // Function to load user from Firestore with caching
34- const loadUserFromFirestore = useCallback ( async ( uid : string ) : Promise < User | null > => {
35- // Check cache first
36- const cached = userCache . get ( uid ) ;
37- if ( cached && Date . now ( ) - cached . timestamp < CACHE_TIMEOUT ) {
38- return cached . user ;
39- }
40-
41- try {
42- const userData = await getUserFromFirestore ( uid ) ;
43- const appUser : User = {
44- id : userData . id ,
45- displayName : userData . displayName ,
46- email : userData . email ,
47- plan : userData . plan ,
48- messagesRemaining : userData . messagesRemaining ,
49- } ;
50-
51- // Update cache
52- setUserCache ( prev => new Map ( prev ) . set ( uid , { user : appUser , timestamp : Date . now ( ) } ) ) ;
53-
54- return appUser ;
55- } catch ( error ) {
56- console . error ( 'Error fetching user data:' , error ) ;
57- return null ;
58- }
59- } , [ userCache , CACHE_TIMEOUT ] ) ;
60-
61- // Firebase auth state listener
62- useEffect ( ( ) => {
63- const unsubscribe = onAuthStateChanged ( auth , async ( firebaseUser ) => {
64- setIsLoading ( true ) ;
65-
66- if ( firebaseUser ) {
67- const userData = await loadUserFromFirestore ( firebaseUser . uid ) ;
68- setUser ( userData ) ;
69- } else {
70- setUser ( null ) ;
71- // Clear cache when user logs out
72- setUserCache ( new Map ( ) ) ;
73- }
74-
75- setIsLoading ( false ) ;
76- setIsInitialized ( true ) ;
77- } ) ;
78-
79- return ( ) => unsubscribe ( ) ;
80- } , [ loadUserFromFirestore ] ) ;
8126
8227 // Function to manually load user state when needed
8328 const loadUserState = useCallback ( async ( ) => {
8429 setIsLoading ( true ) ;
8530 const firebaseUser = auth . currentUser ;
8631
8732 if ( firebaseUser ) {
88- const userData = await loadUserFromFirestore ( firebaseUser . uid ) ;
89- setUser ( userData ) ;
33+ try {
34+ const userData = await getUserFromFirestore ( firebaseUser . uid ) ;
35+ const appUser : User = {
36+ id : userData . id ,
37+ displayName : userData . displayName ,
38+ email : userData . email ,
39+ plan : userData . plan ,
40+ messagesRemaining : userData . messagesRemaining ,
41+ } ;
42+ setUser ( appUser ) ;
43+ } catch ( error ) {
44+ console . error ( 'Error fetching user data:' , error ) ;
45+ setUser ( null ) ;
46+ }
9047 } else {
9148 setUser ( null ) ;
9249 }
9350 setIsLoading ( false ) ;
94- } , [ loadUserFromFirestore ] ) ;
51+ } , [ ] ) ;
9552
9653 const login = async ( credential : string , provider : 'google' | 'apple' = 'google' ) : Promise < void > => {
9754 try {
@@ -143,18 +100,23 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({children}) => {
143100 const firebaseUser = auth . currentUser ;
144101 if ( ! firebaseUser ) return ;
145102
146- // Clear cache for this user to force refresh
147- setUserCache ( prev => {
148- const newCache = new Map ( prev ) ;
149- newCache . delete ( firebaseUser . uid ) ;
150- return newCache ;
151- } ) ;
152-
153- const userData = await loadUserFromFirestore ( firebaseUser . uid ) ;
154- if ( userData ) {
155- setUser ( userData ) ;
103+ try {
104+ const userData = await getUserFromFirestore ( firebaseUser . uid ) ;
105+ if ( userData ) {
106+ const appUser : User = {
107+ id : userData . id ,
108+ displayName : userData . displayName ,
109+ email : userData . email ,
110+ plan : userData . plan ,
111+ messagesRemaining : userData . messagesRemaining ,
112+ } ;
113+
114+ setUser ( appUser ) ;
115+ }
116+ } catch ( error ) {
117+ console . error ( 'Failed to refresh user data:' , error ) ;
156118 }
157- } , [ loadUserFromFirestore ] ) ;
119+ } , [ ] ) ;
158120
159121 const loginWithApple = async ( ) : Promise < void > => {
160122 try {
@@ -189,7 +151,6 @@ export const AuthProvider: React.FC<AuthProviderProps> = ({children}) => {
189151 const value : AuthContextType = {
190152 user,
191153 isLoading,
192- isInitialized,
193154 loadUserState,
194155 login,
195156 loginWithApple,
0 commit comments