@umituz/web-firebase 2.1.1 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/package.json +12 -39
  2. package/src/domain/interfaces/auth.repository.interface.ts +4 -19
  3. package/src/domain/interfaces/file.repository.interface.ts +5 -102
  4. package/src/domain/interfaces/index.ts +7 -0
  5. package/src/domain/interfaces/user.repository.interface.ts +17 -44
  6. package/src/domains/auth/entities/index.ts +60 -0
  7. package/src/domains/auth/index.ts +13 -0
  8. package/src/domains/auth/services/auth.service.ts +245 -0
  9. package/src/domains/auth/services/index.ts +7 -0
  10. package/src/domains/auth/types/auth-service.interface.ts +72 -0
  11. package/src/domains/auth/types/index.ts +5 -0
  12. package/src/domains/firestore/entities/index.ts +82 -0
  13. package/src/domains/firestore/index.ts +13 -0
  14. package/src/domains/firestore/services/firestore.service.ts +191 -0
  15. package/src/domains/firestore/services/index.ts +7 -0
  16. package/src/domains/firestore/types/firestore-service.interface.ts +64 -0
  17. package/src/domains/firestore/types/index.ts +5 -0
  18. package/src/domains/storage/entities/index.ts +94 -0
  19. package/src/domains/storage/index.ts +13 -0
  20. package/src/domains/storage/services/index.ts +7 -0
  21. package/src/domains/storage/services/storage.service.ts +223 -0
  22. package/src/domains/storage/types/index.ts +5 -0
  23. package/src/domains/storage/types/storage-service.interface.ts +120 -0
  24. package/src/index.ts +12 -16
  25. package/src/presentation/hooks/useAuth.ts +69 -26
  26. package/src/presentation/providers/FirebaseProvider.tsx +9 -14
  27. package/dist/application/index.d.mts +0 -273
  28. package/dist/application/index.d.ts +0 -273
  29. package/dist/application/index.js +0 -490
  30. package/dist/application/index.mjs +0 -19
  31. package/dist/chunk-34DL2QWQ.mjs +0 -87
  32. package/dist/chunk-4FP2ELQ5.mjs +0 -96
  33. package/dist/chunk-7TX3OU3O.mjs +0 -721
  34. package/dist/chunk-I6WGBPFB.mjs +0 -439
  35. package/dist/chunk-RZ4QR6TB.mjs +0 -96
  36. package/dist/chunk-U2XI4MGO.mjs +0 -397
  37. package/dist/domain/index.d.mts +0 -325
  38. package/dist/domain/index.d.ts +0 -325
  39. package/dist/domain/index.js +0 -662
  40. package/dist/domain/index.mjs +0 -36
  41. package/dist/file.repository.interface-v5vHgVsZ.d.mts +0 -241
  42. package/dist/file.repository.interface-v5vHgVsZ.d.ts +0 -241
  43. package/dist/firebase.entity-xvfEPjXZ.d.mts +0 -15
  44. package/dist/firebase.entity-xvfEPjXZ.d.ts +0 -15
  45. package/dist/index.d.mts +0 -14
  46. package/dist/index.d.ts +0 -14
  47. package/dist/index.js +0 -1833
  48. package/dist/index.mjs +0 -98
  49. package/dist/infrastructure/index.d.mts +0 -170
  50. package/dist/infrastructure/index.d.ts +0 -170
  51. package/dist/infrastructure/index.js +0 -856
  52. package/dist/infrastructure/index.mjs +0 -46
  53. package/dist/presentation/index.d.mts +0 -25
  54. package/dist/presentation/index.d.ts +0 -25
  55. package/dist/presentation/index.js +0 -105
  56. package/dist/presentation/index.mjs +0 -6
  57. package/dist/user.repository.interface-DS74TsJ5.d.mts +0 -298
  58. package/dist/user.repository.interface-DS74TsJ5.d.ts +0 -298
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Storage Service
3
+ * @description Firebase Storage implementation of IStorageService
4
+ */
5
+
6
+ import {
7
+ ref,
8
+ uploadBytes,
9
+ uploadBytesResumable,
10
+ getDownloadURL,
11
+ deleteObject,
12
+ listAll,
13
+ getMetadata,
14
+ } from 'firebase/storage'
15
+ import { getFirebaseStorage } from '../../../infrastructure/firebase/client'
16
+ import type { IStorageService } from '../types'
17
+ import type {
18
+ UploadResult,
19
+ UploadOptions,
20
+ } from '../entities'
21
+
22
+ class StorageService implements IStorageService {
23
+ private get storage() {
24
+ return getFirebaseStorage()
25
+ }
26
+
27
+ // Upload Methods
28
+
29
+ async uploadFile(
30
+ userId: string,
31
+ path: string,
32
+ file: File | Blob,
33
+ options?: UploadOptions
34
+ ): Promise<UploadResult> {
35
+ const storageRef = ref(this.storage, `users/${userId}/${path}`)
36
+ const uploadTask = uploadBytesResumable(storageRef, file)
37
+
38
+ return new Promise((resolve, reject) => {
39
+ uploadTask.on(
40
+ 'state_changed',
41
+ (snapshot) => {
42
+ if (options?.onProgress) {
43
+ const progress = {
44
+ bytesTransferred: snapshot.bytesTransferred,
45
+ totalBytes: snapshot.totalBytes,
46
+ progress: (snapshot.bytesTransferred / snapshot.totalBytes) * 100,
47
+ state: 'running' as const,
48
+ }
49
+ options.onProgress(progress)
50
+ }
51
+ },
52
+ () => reject(new Error('Upload failed')),
53
+ async () => {
54
+ const downloadURL = await getDownloadURL(uploadTask.snapshot.ref)
55
+ const metadata = await getMetadata(uploadTask.snapshot.ref)
56
+
57
+ resolve({
58
+ id: uploadTask.snapshot.ref.name,
59
+ name: metadata.name || uploadTask.snapshot.ref.name,
60
+ fullPath: metadata.fullPath || uploadTask.snapshot.ref.fullPath,
61
+ downloadURL,
62
+ contentType: metadata.contentType || '',
63
+ size: metadata.size || 0,
64
+ createdAt: metadata.timeCreated ? new Date(metadata.timeCreated).getTime() : Date.now(),
65
+ })
66
+ }
67
+ )
68
+ })
69
+ }
70
+
71
+ async uploadImage(userId: string, file: File, filename?: string): Promise<UploadResult> {
72
+ const name = filename || `${Date.now()}_${file.name}`
73
+ return this.uploadFile(userId, `images/${name}`, file)
74
+ }
75
+
76
+ async uploadVideo(userId: string, file: File, filename?: string): Promise<UploadResult> {
77
+ const name = filename || `${Date.now()}_${file.name}`
78
+ return this.uploadFile(userId, `videos/${name}`, file)
79
+ }
80
+
81
+ async uploadDocument(userId: string, file: File, filename?: string): Promise<UploadResult> {
82
+ const name = filename || `${Date.now()}_${file.name}`
83
+ return this.uploadFile(userId, `documents/${name}`, file)
84
+ }
85
+
86
+ async uploadProfilePicture(userId: string, file: File): Promise<UploadResult> {
87
+ const storageRef = ref(this.storage, `users/${userId}/profile/${Date.now()}_${file.name}`)
88
+ await uploadBytes(storageRef, file)
89
+ const downloadURL = await getDownloadURL(storageRef)
90
+
91
+ return {
92
+ id: storageRef.name,
93
+ name: file.name,
94
+ fullPath: storageRef.fullPath,
95
+ downloadURL,
96
+ contentType: file.type,
97
+ size: file.size,
98
+ createdAt: Date.now(),
99
+ }
100
+ }
101
+
102
+ // Download Methods
103
+
104
+ async getDownloadURL(path: string): Promise<string> {
105
+ try {
106
+ const storageRef = ref(this.storage, path)
107
+ return await getDownloadURL(storageRef)
108
+ } catch {
109
+ throw new Error('File not found')
110
+ }
111
+ }
112
+
113
+ // Delete Methods
114
+
115
+ async deleteFile(path: string): Promise<void> {
116
+ try {
117
+ const storageRef = ref(this.storage, path)
118
+ await deleteObject(storageRef)
119
+ } catch {
120
+ throw new Error('File not found')
121
+ }
122
+ }
123
+
124
+ async deleteUserFiles(userId: string): Promise<void> {
125
+ try {
126
+ const userRef = ref(this.storage, `users/${userId}`)
127
+ const result = await listAll(userRef)
128
+
129
+ // Delete all files in all prefixes
130
+ for (const prefix of result.prefixes) {
131
+ const prefixResult = await listAll(prefix)
132
+ await Promise.all(prefixResult.items.map((item) => deleteObject(item)))
133
+ }
134
+
135
+ // Delete all files in root
136
+ await Promise.all(result.items.map((item) => deleteObject(item)))
137
+ } catch {
138
+ throw new Error('Failed to delete user files')
139
+ }
140
+ }
141
+
142
+ async deleteImage(userId: string, filename: string): Promise<void> {
143
+ await this.deleteFile(`users/${userId}/images/${filename}`)
144
+ }
145
+
146
+ async deleteVideo(userId: string, filename: string): Promise<void> {
147
+ await this.deleteFile(`users/${userId}/videos/${filename}`)
148
+ }
149
+
150
+ async deleteProfilePicture(userId: string, filename: string): Promise<void> {
151
+ await this.deleteFile(`users/${userId}/profile/${filename}`)
152
+ }
153
+
154
+ // List Methods
155
+
156
+ async listUserFiles(userId: string, path?: string): Promise<string[]> {
157
+ const userRef = ref(this.storage, path ? `users/${userId}/${path}` : `users/${userId}`)
158
+ const result = await listAll(userRef)
159
+
160
+ const urls = await Promise.all(result.items.map((item) => getDownloadURL(item)))
161
+ return urls
162
+ }
163
+
164
+ async listUserImages(userId: string): Promise<string[]> {
165
+ return this.listUserFiles(userId, 'images')
166
+ }
167
+
168
+ async listUserVideos(userId: string): Promise<string[]> {
169
+ return this.listUserFiles(userId, 'videos')
170
+ }
171
+
172
+ // Validation
173
+
174
+ validateFile(file: File, options?: { maxSizeBytes?: number; maxSizeMB?: number; allowedTypes?: string[] }): boolean {
175
+ const maxSizeBytes = options?.maxSizeBytes || (options?.maxSizeMB ? options.maxSizeMB * 1024 * 1024 : 10 * 1024 * 1024)
176
+
177
+ if (file.size > maxSizeBytes) {
178
+ return false
179
+ }
180
+
181
+ if (options?.allowedTypes && !options.allowedTypes.includes(file.type)) {
182
+ return false
183
+ }
184
+
185
+ return true
186
+ }
187
+
188
+ isImageFile(file: File): boolean {
189
+ return file.type.startsWith('image/')
190
+ }
191
+
192
+ isVideoFile(file: File): boolean {
193
+ return file.type.startsWith('video/')
194
+ }
195
+
196
+ isDocumentFile(file: File): boolean {
197
+ const docTypes = [
198
+ 'application/pdf',
199
+ 'application/msword',
200
+ 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
201
+ 'application/vnd.ms-excel',
202
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
203
+ 'text/plain',
204
+ ]
205
+ return docTypes.includes(file.type)
206
+ }
207
+
208
+ // Utility Methods
209
+
210
+ generateUniqueFilename(originalName: string): string {
211
+ const timestamp = Date.now()
212
+ const random = Math.random().toString(36).substring(2, 8)
213
+ const extension = this.getFileExtension(originalName)
214
+ return `${timestamp}_${random}.${extension}`
215
+ }
216
+
217
+ getFileExtension(filename: string): string {
218
+ return filename.slice(((filename.lastIndexOf('.') - 1) >>> 0) + 2)
219
+ }
220
+ }
221
+
222
+ // Export class and singleton instance
223
+ export const storageService = new StorageService()
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Storage Domain Types
3
+ */
4
+
5
+ export * from './storage-service.interface'
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Storage Service Interface
3
+ * @description Abstract interface for storage operations
4
+ */
5
+
6
+ import type {
7
+ UploadResult,
8
+ UploadOptions,
9
+ } from '../entities'
10
+
11
+ export interface IStorageService {
12
+ /**
13
+ * Upload file to storage
14
+ */
15
+ uploadFile(
16
+ userId: string,
17
+ path: string,
18
+ file: File | Blob,
19
+ options?: UploadOptions
20
+ ): Promise<UploadResult>
21
+
22
+ /**
23
+ * Upload image with automatic categorization
24
+ */
25
+ uploadImage(userId: string, file: File, filename?: string): Promise<UploadResult>
26
+
27
+ /**
28
+ * Upload video with automatic categorization
29
+ */
30
+ uploadVideo(userId: string, file: File, filename?: string): Promise<UploadResult>
31
+
32
+ /**
33
+ * Upload document with automatic categorization
34
+ */
35
+ uploadDocument(userId: string, file: File, filename?: string): Promise<UploadResult>
36
+
37
+ /**
38
+ * Upload profile picture
39
+ */
40
+ uploadProfilePicture(userId: string, file: File): Promise<UploadResult>
41
+
42
+ /**
43
+ * Get download URL for a file
44
+ */
45
+ getDownloadURL(path: string): Promise<string>
46
+
47
+ /**
48
+ * Delete file by path
49
+ */
50
+ deleteFile(path: string): Promise<void>
51
+
52
+ /**
53
+ * Delete all user files
54
+ */
55
+ deleteUserFiles(userId: string): Promise<void>
56
+
57
+ /**
58
+ * Delete user image
59
+ */
60
+ deleteImage(userId: string, filename: string): Promise<void>
61
+
62
+ /**
63
+ * Delete user video
64
+ */
65
+ deleteVideo(userId: string, filename: string): Promise<void>
66
+
67
+ /**
68
+ * Delete profile picture
69
+ */
70
+ deleteProfilePicture(userId: string, filename: string): Promise<void>
71
+
72
+ /**
73
+ * List user files
74
+ */
75
+ listUserFiles(userId: string, path?: string): Promise<string[]>
76
+
77
+ /**
78
+ * List user images
79
+ */
80
+ listUserImages(userId: string): Promise<string[]>
81
+
82
+ /**
83
+ * List user videos
84
+ */
85
+ listUserVideos(userId: string): Promise<string[]>
86
+
87
+ /**
88
+ * Validate file before upload
89
+ */
90
+ validateFile(file: File, options?: {
91
+ maxSizeBytes?: number
92
+ maxSizeMB?: number
93
+ allowedTypes?: string[]
94
+ }): boolean
95
+
96
+ /**
97
+ * Check if file is an image
98
+ */
99
+ isImageFile(file: File): boolean
100
+
101
+ /**
102
+ * Check if file is a video
103
+ */
104
+ isVideoFile(file: File): boolean
105
+
106
+ /**
107
+ * Check if file is a document
108
+ */
109
+ isDocumentFile(file: File): boolean
110
+
111
+ /**
112
+ * Generate unique filename
113
+ */
114
+ generateUniqueFilename(originalName: string): string
115
+
116
+ /**
117
+ * Get file extension
118
+ */
119
+ getFileExtension(filename: string): string
120
+ }
package/src/index.ts CHANGED
@@ -1,23 +1,19 @@
1
1
  /**
2
2
  * @umituz/web-firebase
3
- * Comprehensive Firebase integration with DDD architecture
3
+ * Firebase integration for web applications with domain-based architecture
4
4
  *
5
- * ONEMLI: App'ler bu root barrel'i kullanMAMALI.
6
- * Subpath import kullanin:
7
- * - "@umituz/web-firebase/domain" - Domain entities, value objects, interfaces
8
- * - "@umituz/web-firebase/application" - Use cases and DTOs
9
- * - "@umituz/web-firebase/infrastructure" - Firebase adapters
10
- * - "@umituz/web-firebase/presentation" - React hooks and providers
5
+ * Usage:
6
+ * import { AuthService } from '@umituz/web-firebase/auth'
7
+ * import { FirestoreService } from '@umituz/web-firebase/firestore'
8
+ * import { StorageService } from '@umituz/web-firebase/storage'
11
9
  */
12
10
 
13
- // Domain entities, value objects, interfaces, errors
14
- export * from './domain'
11
+ // Firebase client initialization
12
+ export * from './infrastructure/firebase/client'
15
13
 
16
- // Application use cases and DTOs
17
- export * from './application'
14
+ // React components
15
+ export { FirebaseProvider, useFirebaseContext } from './presentation/providers/FirebaseProvider'
18
16
 
19
- // Infrastructure Firebase adapters
20
- export * from './infrastructure'
21
-
22
- // Presentation hooks and providers
23
- export * from './presentation'
17
+ // Re-export common types for convenience
18
+ export type { FirebaseInstances } from './infrastructure/firebase/client'
19
+ export type { FirebaseContextValue, FirebaseProviderProps } from './presentation/providers/FirebaseProvider'
@@ -1,19 +1,19 @@
1
1
  /**
2
2
  * Auth Hook
3
3
  * @description React hook for authentication operations
4
- * Uses FirebaseProvider context - no repository injection needed
4
+ * Uses new domain services - no adapter injection needed
5
5
  */
6
6
 
7
- import { useCallback } from 'react'
7
+ import { useCallback, useEffect, useState } from 'react'
8
8
  import type { User as FirebaseUser } from 'firebase/auth'
9
- import type { User } from '../../domain/entities/user.entity'
10
- import { AuthAdapter } from '../../infrastructure/firebase/auth.adapter'
11
- import { FirestoreAdapter } from '../../infrastructure/firebase/firestore.adapter'
9
+ import type { User as FirestoreUser } from '../../domains/firestore/entities'
10
+ import { authService } from '../../domains/auth/services'
11
+ import { firestoreService } from '../../domains/firestore/services'
12
12
  import { useFirebaseContext } from '../providers/FirebaseProvider'
13
13
 
14
14
  export interface UseAuthResult {
15
15
  firebaseUser: FirebaseUser | null
16
- user: User | null
16
+ user: FirestoreUser | null
17
17
  loading: boolean
18
18
  error: Error | null
19
19
  isAuthenticated: boolean
@@ -29,62 +29,106 @@ export interface UseAuthResult {
29
29
  }
30
30
 
31
31
  export function useAuth(): UseAuthResult {
32
- const { instances, user, loading, error } = useFirebaseContext()
33
-
34
- const authAdapter = new AuthAdapter()
35
- const firestoreAdapter = new FirestoreAdapter()
32
+ const { instances, loading, error } = useFirebaseContext()
33
+ const [user, setUser] = useState<FirestoreUser | null>(null)
34
+
35
+ useEffect(() => {
36
+ const fetchUser = async () => {
37
+ const currentUser = instances?.auth.currentUser
38
+ if (currentUser) {
39
+ const userData = await firestoreService.getUser(currentUser.uid)
40
+ setUser(userData)
41
+ } else {
42
+ setUser(null)
43
+ }
44
+ }
45
+ fetchUser()
46
+ }, [instances?.auth.currentUser])
36
47
 
37
48
  const signIn = useCallback(async (email: string, password: string) => {
38
- return await authAdapter.signIn(email, password)
49
+ const result = await authService.signIn(email, password)
50
+ return result.user
39
51
  }, [])
40
52
 
41
53
  const signUp = useCallback(async (email: string, password: string, displayName: string) => {
42
- const userCredential = await authAdapter.signUp(email, password, displayName)
54
+ const userCredential = await authService.signUp(email, password, displayName)
43
55
 
44
56
  // Create user profile in Firestore
45
- await firestoreAdapter.createUser(userCredential.user.uid, {
57
+ const now = Date.now()
58
+ await firestoreService.createUser(userCredential.user.uid, {
46
59
  profile: {
60
+ id: userCredential.user.uid,
47
61
  email: email,
48
62
  displayName: displayName,
49
- createdAt: Date.now(),
63
+ createdAt: now,
64
+ updatedAt: now,
65
+ lastLoginAt: now,
66
+ emailVerified: false,
50
67
  },
51
68
  settings: {
52
69
  theme: 'light',
53
70
  language: 'tr',
71
+ timezone: 'Europe/Istanbul',
72
+ currency: 'TRY',
73
+ notifications: {
74
+ email: true,
75
+ push: true,
76
+ marketing: false,
77
+ security: true,
78
+ weeklyDigest: false,
79
+ },
80
+ privacy: {
81
+ profileVisibility: 'public',
82
+ showEmail: false,
83
+ showPhone: false,
84
+ dataSharing: false,
85
+ },
86
+ },
87
+ subscription: {
88
+ plan: 'free',
89
+ status: 'active',
90
+ cancelAtPeriodEnd: false,
91
+ createdAt: now,
92
+ updatedAt: now,
54
93
  },
55
94
  })
56
95
 
57
96
  return userCredential.user
58
97
  }, [])
59
98
 
60
- const signInWithGoogle = useCallback(async () => {
61
- return await authAdapter.signInWithGoogle()
99
+ const signInWithGoogleCallback = useCallback(async () => {
100
+ const result = await authService.signInWithGoogle()
101
+ return result.user
62
102
  }, [])
63
103
 
64
104
  const signOut = useCallback(async () => {
65
- await authAdapter.signOut()
105
+ await authService.signOut()
66
106
  }, [])
67
107
 
68
108
  const sendPasswordReset = useCallback(async (email: string) => {
69
- await authAdapter.sendPasswordReset(email)
109
+ await authService.sendPasswordReset(email)
70
110
  }, [])
71
111
 
72
112
  const resendEmailVerification = useCallback(async () => {
73
- await authAdapter.resendEmailVerification()
113
+ await authService.resendEmailVerification()
74
114
  }, [])
75
115
 
76
116
  const updateProfile = useCallback(async (updates: { displayName?: string; photoURL?: string }) => {
77
- await authAdapter.updateProfile(updates)
117
+ await authService.updateProfile(updates)
78
118
 
79
119
  // Refresh user data from Firestore if available
80
- if (instances?.auth.currentUser) {
81
- await firestoreAdapter.getUser(instances.auth.currentUser.uid)
120
+ const currentUser = instances?.auth.currentUser
121
+ if (currentUser) {
122
+ const userData = await firestoreService.getUser(currentUser.uid)
123
+ setUser(userData)
82
124
  }
83
125
  }, [instances])
84
126
 
85
127
  const refreshUser = useCallback(async () => {
86
- if (instances?.auth.currentUser) {
87
- await firestoreAdapter.getUser(instances.auth.currentUser.uid)
128
+ const currentUser = instances?.auth.currentUser
129
+ if (currentUser) {
130
+ const userData = await firestoreService.getUser(currentUser.uid)
131
+ setUser(userData)
88
132
  }
89
133
  }, [instances])
90
134
 
@@ -97,7 +141,7 @@ export function useAuth(): UseAuthResult {
97
141
  isEmailVerified: instances?.auth.currentUser?.emailVerified || false,
98
142
  signIn,
99
143
  signUp,
100
- signInWithGoogle,
144
+ signInWithGoogle: signInWithGoogleCallback,
101
145
  signOut,
102
146
  sendPasswordReset,
103
147
  resendEmailVerification,
@@ -105,4 +149,3 @@ export function useAuth(): UseAuthResult {
105
149
  refreshUser,
106
150
  }
107
151
  }
108
-
@@ -7,12 +7,14 @@ import { createContext, useContext, useState, useEffect, type ReactNode } from '
7
7
  import type { User } from 'firebase/auth'
8
8
  import type { FirebaseInstances } from '../../infrastructure/firebase/client'
9
9
  import { getFirebaseInstances } from '../../infrastructure/firebase/client'
10
- import { AuthAdapter } from '../../infrastructure/firebase/auth.adapter'
10
+ import type { AuthUser } from '../../domains/auth/entities'
11
+ import { authService } from '../../domains/auth/services'
11
12
 
12
13
  export interface FirebaseContextValue {
13
14
  instances: FirebaseInstances
14
15
  isInitialized: boolean
15
16
  user: User | null
17
+ authUser: AuthUser | null
16
18
  loading: boolean
17
19
  error: Error | null
18
20
  }
@@ -34,6 +36,7 @@ export interface FirebaseProviderProps {
34
36
  export function FirebaseProvider({ children, config }: FirebaseProviderProps) {
35
37
  const [instances, setInstances] = useState<FirebaseInstances | null>(null)
36
38
  const [user, setUser] = useState<User | null>(null)
39
+ const [authUser, setAuthUser] = useState<AuthUser | null>(null)
37
40
  const [loading, setLoading] = useState(true)
38
41
  const [error, setError] = useState<Error | null>(null)
39
42
 
@@ -44,10 +47,10 @@ export function FirebaseProvider({ children, config }: FirebaseProviderProps) {
44
47
  setInstances(firebaseInstances)
45
48
 
46
49
  // Set up auth state listener
47
- const authAdapter = new AuthAdapter()
48
- const unsubscribe = authAdapter.onAuthStateChanged(
49
- (user) => {
50
- setUser(user)
50
+ const unsubscribe = authService.onAuthStateChanged(
51
+ (newAuthUser) => {
52
+ setAuthUser(newAuthUser)
53
+ setUser(newAuthUser ? (firebaseInstances.auth.currentUser || null) : null)
51
54
  setLoading(false)
52
55
  setError(null)
53
56
  },
@@ -70,18 +73,11 @@ export function FirebaseProvider({ children, config }: FirebaseProviderProps) {
70
73
  instances: instances!,
71
74
  isInitialized: !!instances,
72
75
  user,
76
+ authUser,
73
77
  loading,
74
78
  error,
75
79
  }
76
80
 
77
- if (!instances || loading) {
78
- return (
79
- <FirebaseContext.Provider value={{ ...value, isInitialized: false }}>
80
- {children}
81
- </FirebaseContext.Provider>
82
- )
83
- }
84
-
85
81
  return <FirebaseContext.Provider value={value}>{children}</FirebaseContext.Provider>
86
82
  }
87
83
 
@@ -92,4 +88,3 @@ export function useFirebaseContext(): FirebaseContextValue {
92
88
  }
93
89
  return context
94
90
  }
95
-