@umituz/web-firebase 3.2.3 → 3.3.0
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.
- package/package.json +5 -2
- package/src/application/use-cases/auth/sign-in-with-google.use-case.ts +13 -11
- package/src/domain/interfaces/file.repository.interface.ts +28 -3
- package/src/domain/interfaces/user.repository.interface.ts +12 -40
- package/src/domains/firestore/services/firestore.service.ts +5 -1
- package/src/domains/storage/services/storage.service.ts +5 -1
- package/src/index.ts +2 -11
- package/src/infrastructure/firebase/auth.adapter.ts +7 -3
- package/src/infrastructure/firebase/client.ts +98 -44
- package/src/infrastructure/firebase/firestore.adapter.ts +5 -1
- package/src/infrastructure/firebase/storage.adapter.ts +5 -1
- package/src/presentation/hooks/useAuth.ts +0 -392
- package/src/presentation/hooks/useFirebaseAuth.ts +0 -122
- package/src/presentation/hooks/useFirestore.ts +0 -125
- package/src/presentation/hooks/useStorage.ts +0 -141
- package/src/presentation/index.ts +0 -10
- package/src/presentation/providers/FirebaseProvider.tsx +0 -90
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/web-firebase",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"description": "Comprehensive Firebase integration with domain-based architecture for web applications",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -21,7 +21,10 @@
|
|
|
21
21
|
"src"
|
|
22
22
|
],
|
|
23
23
|
"scripts": {
|
|
24
|
-
"
|
|
24
|
+
"build": "npm run clean && tsc",
|
|
25
|
+
"clean": "rm -rf dist",
|
|
26
|
+
"typecheck": "tsc --noEmit",
|
|
27
|
+
"prepublishOnly": "npm run build"
|
|
25
28
|
},
|
|
26
29
|
"keywords": [
|
|
27
30
|
"firebase",
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
import type { UserCredential } from 'firebase/auth'
|
|
7
7
|
import type { IAuthRepository } from '../../../domain/interfaces/auth.repository.interface'
|
|
8
8
|
import type { IUserRepository } from '../../../domain/interfaces/user.repository.interface'
|
|
9
|
-
import type { CreateUserDTO } from '../../dto/user.dto'
|
|
10
9
|
import { createAuthError, AuthErrorCode } from '../../../domain/errors/auth.errors'
|
|
11
10
|
|
|
12
11
|
export class SignInWithGoogleUseCase {
|
|
@@ -27,16 +26,19 @@ export class SignInWithGoogleUseCase {
|
|
|
27
26
|
const existingUser = await this.userRepository.getUser(result.user.uid)
|
|
28
27
|
if (!existingUser) {
|
|
29
28
|
// New user - create user document
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
29
|
+
await this.userRepository.createUser(result.user.uid, {
|
|
30
|
+
profile: {
|
|
31
|
+
id: result.user.uid,
|
|
32
|
+
email: result.user.email || '',
|
|
33
|
+
displayName: result.user.displayName || '',
|
|
34
|
+
photoURL: result.user.photoURL || undefined,
|
|
35
|
+
phoneNumber: result.user.phoneNumber || undefined,
|
|
36
|
+
emailVerified: result.user.emailVerified,
|
|
37
|
+
createdAt: Date.now(),
|
|
38
|
+
updatedAt: Date.now(),
|
|
39
|
+
lastLoginAt: Date.now(),
|
|
40
|
+
}
|
|
41
|
+
} as any)
|
|
40
42
|
}
|
|
41
43
|
|
|
42
44
|
return result
|
|
@@ -3,21 +3,33 @@
|
|
|
3
3
|
* @description Generic contract for file storage operations
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import type { UploadResult, UploadOptions } from '../entities/file.entity'
|
|
7
|
+
|
|
6
8
|
export interface IFileRepository {
|
|
7
9
|
/**
|
|
8
10
|
* Upload file to storage
|
|
9
11
|
*/
|
|
10
|
-
uploadFile(userId: string, path: string, file: File | Blob, options?:
|
|
12
|
+
uploadFile(userId: string, path: string, file: File | Blob, options?: UploadOptions): Promise<UploadResult>
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* Upload image with automatic categorization
|
|
14
16
|
*/
|
|
15
|
-
uploadImage(userId: string, file: File, filename?: string): Promise<
|
|
17
|
+
uploadImage(userId: string, file: File, filename?: string): Promise<UploadResult>
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Upload video with automatic categorization
|
|
21
|
+
*/
|
|
22
|
+
uploadVideo(userId: string, file: File, filename?: string): Promise<UploadResult>
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Upload document with automatic categorization
|
|
26
|
+
*/
|
|
27
|
+
uploadDocument(userId: string, file: File, filename?: string): Promise<UploadResult>
|
|
16
28
|
|
|
17
29
|
/**
|
|
18
30
|
* Upload profile picture
|
|
19
31
|
*/
|
|
20
|
-
uploadProfilePicture(userId: string, file: File): Promise<
|
|
32
|
+
uploadProfilePicture(userId: string, file: File): Promise<UploadResult>
|
|
21
33
|
|
|
22
34
|
/**
|
|
23
35
|
* Get download URL for a file
|
|
@@ -34,11 +46,24 @@ export interface IFileRepository {
|
|
|
34
46
|
*/
|
|
35
47
|
deleteUserFiles(userId: string): Promise<void>
|
|
36
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Delete specific media types
|
|
51
|
+
*/
|
|
52
|
+
deleteImage(userId: string, filename: string): Promise<void>
|
|
53
|
+
deleteVideo(userId: string, filename: string): Promise<void>
|
|
54
|
+
deleteProfilePicture(userId: string, filename: string): Promise<void>
|
|
55
|
+
|
|
37
56
|
/**
|
|
38
57
|
* List user files
|
|
39
58
|
*/
|
|
40
59
|
listUserFiles(userId: string, path?: string): Promise<string[]>
|
|
41
60
|
|
|
61
|
+
/**
|
|
62
|
+
* List specific media types
|
|
63
|
+
*/
|
|
64
|
+
listUserImages(userId: string): Promise<string[]>
|
|
65
|
+
listUserVideos(userId: string): Promise<string[]>
|
|
66
|
+
|
|
42
67
|
/**
|
|
43
68
|
* Validate file before upload
|
|
44
69
|
*/
|
|
@@ -3,46 +3,18 @@
|
|
|
3
3
|
* @description Generic contract for user data operations
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import type {
|
|
6
|
+
import type { User } from '../entities/user.entity'
|
|
7
7
|
|
|
8
8
|
export interface IUserRepository {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
* Create document
|
|
21
|
-
*/
|
|
22
|
-
create(userId: string, data: any): Promise<void>
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Update document
|
|
26
|
-
*/
|
|
27
|
-
update(userId: string, data: any, options?: { merge?: boolean }): Promise<void>
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Delete document
|
|
31
|
-
*/
|
|
32
|
-
delete(userId: string): Promise<void>
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Query collection with constraints
|
|
36
|
-
*/
|
|
37
|
-
query<T>(collectionPath: string, constraints: QueryConstraint[]): Promise<T[]>
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Subscribe to document changes
|
|
41
|
-
*/
|
|
42
|
-
subscribeToDoc<T>(docPath: string, callback: (data: T | null) => void): () => void
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Subscribe to collection changes
|
|
46
|
-
*/
|
|
47
|
-
subscribeToCollection<T>(collectionPath: string, callback: (data: T[]) => void, constraints?: QueryConstraint[]): () => void
|
|
9
|
+
getUser(userId: string): Promise<User | null>
|
|
10
|
+
getUserByEmail(email: string): Promise<User | null>
|
|
11
|
+
createUser(userId: string, data: Partial<User>): Promise<void>
|
|
12
|
+
updateUser(userId: string, data: Partial<User>): Promise<void>
|
|
13
|
+
deleteUser(userId: string): Promise<void>
|
|
14
|
+
updateProfile(userId: string, updates: Partial<Pick<User['profile'], 'displayName' | 'photoURL' | 'phoneNumber'>>): Promise<void>
|
|
15
|
+
updateSettings(userId: string, settings: Partial<User['settings']>): Promise<void>
|
|
16
|
+
updateSubscription(userId: string, subscription: Partial<User['subscription']>): Promise<void>
|
|
17
|
+
updateLastLogin(userId: string): Promise<void>
|
|
18
|
+
queryUsers(constraints: any[]): Promise<User[]>
|
|
19
|
+
subscribeToUser(userId: string, callback: (user: User | null) => void, onError?: (error: Error) => void): () => void
|
|
48
20
|
}
|
|
@@ -21,7 +21,11 @@ import type { User } from '../entities'
|
|
|
21
21
|
|
|
22
22
|
class FirestoreService implements IFirestoreService {
|
|
23
23
|
private get db() {
|
|
24
|
-
|
|
24
|
+
const db = getFirebaseDB()
|
|
25
|
+
if (!db) {
|
|
26
|
+
throw new Error('Firestore not initialized. Call initializeFirebase() first.')
|
|
27
|
+
}
|
|
28
|
+
return db
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
private readonly USERS_COLLECTION = 'users'
|
|
@@ -21,7 +21,11 @@ import type {
|
|
|
21
21
|
|
|
22
22
|
class StorageService implements IStorageService {
|
|
23
23
|
private get storage() {
|
|
24
|
-
|
|
24
|
+
const storage = getFirebaseStorage()
|
|
25
|
+
if (!storage) {
|
|
26
|
+
throw new Error('Firebase Storage not initialized. Call initializeFirebase() first.')
|
|
27
|
+
}
|
|
28
|
+
return storage
|
|
25
29
|
}
|
|
26
30
|
|
|
27
31
|
// Upload Methods
|
package/src/index.ts
CHANGED
|
@@ -1,19 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @umituz/web-firebase
|
|
3
|
-
* Firebase
|
|
3
|
+
* Firebase client initialization and core services
|
|
4
4
|
*
|
|
5
5
|
* Usage:
|
|
6
|
-
* import {
|
|
7
|
-
* import { FirestoreService } from '@umituz/web-firebase/firestore'
|
|
8
|
-
* import { StorageService } from '@umituz/web-firebase/storage'
|
|
6
|
+
* import { initializeFirebase, getFirebaseDB } from '@umituz/web-firebase'
|
|
9
7
|
*/
|
|
10
8
|
|
|
11
9
|
// Firebase client initialization
|
|
12
10
|
export * from './infrastructure/firebase/client'
|
|
13
|
-
|
|
14
|
-
// Presentation Layer (React components & hooks)
|
|
15
|
-
export * from './presentation/index'
|
|
16
|
-
|
|
17
|
-
// Re-export common types for convenience
|
|
18
|
-
export type { FirebaseInstances } from './infrastructure/firebase/client'
|
|
19
|
-
export type { FirebaseContextValue, FirebaseProviderProps } from './presentation/providers/FirebaseProvider'
|
|
@@ -36,7 +36,11 @@ import { getAuthConfig } from '../../domain/config/auth.config'
|
|
|
36
36
|
*/
|
|
37
37
|
export class AuthAdapter implements IAuthRepository {
|
|
38
38
|
private get auth() {
|
|
39
|
-
|
|
39
|
+
const auth = getFirebaseAuth()
|
|
40
|
+
if (!auth) {
|
|
41
|
+
throw new Error('Firebase Auth not initialized. Call initializeFirebase() first.')
|
|
42
|
+
}
|
|
43
|
+
return auth
|
|
40
44
|
}
|
|
41
45
|
|
|
42
46
|
private config = getAuthConfig()
|
|
@@ -320,8 +324,8 @@ export class AuthAdapter implements IAuthRepository {
|
|
|
320
324
|
return this.auth.currentUser
|
|
321
325
|
}
|
|
322
326
|
|
|
323
|
-
onAuthStateChanged(callback: (user: FirebaseUser | null) => void) {
|
|
324
|
-
return this.auth.onAuthStateChanged(callback)
|
|
327
|
+
onAuthStateChanged(callback: (user: FirebaseUser | null) => void, onError?: (error: Error) => void) {
|
|
328
|
+
return this.auth.onAuthStateChanged(callback, onError)
|
|
325
329
|
}
|
|
326
330
|
|
|
327
331
|
// ==================== Token Management ====================
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Firebase Client
|
|
3
3
|
* @description Firebase initialization and singleton instances
|
|
4
|
-
* Migrated from: /Users/
|
|
4
|
+
* Migrated from: /Users/umuz/Desktop/github/umituz/apps/web/app-growth-factory/src/domains/firebase/services/client.ts
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { initializeApp, getApps, FirebaseApp } from 'firebase/app'
|
|
@@ -11,50 +11,75 @@ import { getStorage, FirebaseStorage } from 'firebase/storage'
|
|
|
11
11
|
import { getAnalytics, Analytics } from 'firebase/analytics'
|
|
12
12
|
import { getFunctions, Functions } from 'firebase/functions'
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Firebase Configuration interface
|
|
16
|
+
* Pass this to initializeFirebase()
|
|
17
|
+
*/
|
|
18
|
+
export interface FirebaseConfig {
|
|
19
|
+
apiKey: string
|
|
20
|
+
authDomain: string
|
|
21
|
+
projectId: string
|
|
22
|
+
storageBucket: string
|
|
23
|
+
messagingSenderId: string
|
|
24
|
+
appId: string
|
|
25
|
+
measurementId?: string
|
|
22
26
|
}
|
|
23
27
|
|
|
24
28
|
// Singleton instances
|
|
25
|
-
let app: FirebaseApp
|
|
26
|
-
let auth: Auth
|
|
27
|
-
let db: Firestore
|
|
28
|
-
let storage: FirebaseStorage
|
|
29
|
-
let functions: Functions
|
|
29
|
+
let app: FirebaseApp | null = null
|
|
30
|
+
let auth: Auth | null = null
|
|
31
|
+
let db: Firestore | null = null
|
|
32
|
+
let storage: FirebaseStorage | null = null
|
|
33
|
+
let functions: Functions | null = null
|
|
30
34
|
let analytics: Analytics | null = null
|
|
31
35
|
|
|
32
36
|
/**
|
|
33
|
-
* Initialize Firebase
|
|
37
|
+
* Initialize Firebase with provided configuration
|
|
38
|
+
* Must be called before using any Firebase services
|
|
39
|
+
*
|
|
40
|
+
* @param config - Firebase configuration object
|
|
41
|
+
* @returns FirebaseApp instance
|
|
34
42
|
*/
|
|
35
|
-
export function initializeFirebase(): FirebaseApp {
|
|
36
|
-
if (
|
|
37
|
-
|
|
38
|
-
|
|
43
|
+
export function initializeFirebase(config: FirebaseConfig): FirebaseApp {
|
|
44
|
+
if (app) {
|
|
45
|
+
console.warn('Firebase already initialized')
|
|
46
|
+
return app
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (getApps().length > 0) {
|
|
39
50
|
app = getApps()[0]
|
|
51
|
+
return app
|
|
40
52
|
}
|
|
53
|
+
|
|
54
|
+
// Validate config
|
|
55
|
+
if (!config.apiKey || !config.projectId) {
|
|
56
|
+
throw new Error('Invalid Firebase config: apiKey and projectId are required')
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
app = initializeApp(config)
|
|
41
60
|
return app
|
|
42
61
|
}
|
|
43
62
|
|
|
44
63
|
/**
|
|
45
64
|
* Get Firebase App instance
|
|
65
|
+
* @returns FirebaseApp instance or null if not initialized
|
|
46
66
|
*/
|
|
47
|
-
export function getFirebaseApp(): FirebaseApp {
|
|
48
|
-
return app
|
|
67
|
+
export function getFirebaseApp(): FirebaseApp | null {
|
|
68
|
+
return app
|
|
49
69
|
}
|
|
50
70
|
|
|
51
71
|
/**
|
|
52
72
|
* Get Firebase Auth instance
|
|
73
|
+
* @returns Auth instance or null if not initialized
|
|
53
74
|
*/
|
|
54
|
-
export function getFirebaseAuth(): Auth {
|
|
75
|
+
export function getFirebaseAuth(): Auth | null {
|
|
76
|
+
if (!app) {
|
|
77
|
+
console.warn('Firebase not initialized. Call initializeFirebase(config) first.')
|
|
78
|
+
return null
|
|
79
|
+
}
|
|
55
80
|
if (!auth) {
|
|
56
81
|
const firebaseApp = getFirebaseApp()
|
|
57
|
-
if (typeof window !== 'undefined') {
|
|
82
|
+
if (firebaseApp && typeof window !== 'undefined') {
|
|
58
83
|
try {
|
|
59
84
|
auth = getAuth(firebaseApp)
|
|
60
85
|
} catch (e) {
|
|
@@ -63,7 +88,7 @@ export function getFirebaseAuth(): Auth {
|
|
|
63
88
|
persistence: browserLocalPersistence,
|
|
64
89
|
})
|
|
65
90
|
}
|
|
66
|
-
} else {
|
|
91
|
+
} else if (firebaseApp) {
|
|
67
92
|
auth = getAuth(firebaseApp)
|
|
68
93
|
}
|
|
69
94
|
}
|
|
@@ -72,70 +97,99 @@ export function getFirebaseAuth(): Auth {
|
|
|
72
97
|
|
|
73
98
|
/**
|
|
74
99
|
* Get Firestore instance
|
|
100
|
+
* @returns Firestore instance or null if not initialized
|
|
75
101
|
*/
|
|
76
|
-
export function getFirebaseDB(): Firestore {
|
|
102
|
+
export function getFirebaseDB(): Firestore | null {
|
|
103
|
+
if (!app) {
|
|
104
|
+
console.warn('Firebase not initialized. Call initializeFirebase(config) first.')
|
|
105
|
+
return null
|
|
106
|
+
}
|
|
77
107
|
if (!db) {
|
|
78
|
-
db = getFirestore(getFirebaseApp())
|
|
108
|
+
db = getFirestore(getFirebaseApp()!)
|
|
79
109
|
}
|
|
80
110
|
return db
|
|
81
111
|
}
|
|
82
112
|
|
|
83
113
|
/**
|
|
84
114
|
* Get Firebase Storage instance
|
|
115
|
+
* @returns FirebaseStorage instance or null if not initialized
|
|
85
116
|
*/
|
|
86
|
-
export function getFirebaseStorage(): FirebaseStorage {
|
|
117
|
+
export function getFirebaseStorage(): FirebaseStorage | null {
|
|
118
|
+
if (!app) {
|
|
119
|
+
console.warn('Firebase not initialized. Call initializeFirebase(config) first.')
|
|
120
|
+
return null
|
|
121
|
+
}
|
|
87
122
|
if (!storage) {
|
|
88
|
-
storage = getStorage(getFirebaseApp())
|
|
123
|
+
storage = getStorage(getFirebaseApp()!)
|
|
89
124
|
}
|
|
90
125
|
return storage
|
|
91
126
|
}
|
|
92
127
|
|
|
93
128
|
/**
|
|
94
129
|
* Get Firebase Functions instance
|
|
130
|
+
* @returns Functions instance or null if not initialized
|
|
95
131
|
*/
|
|
96
|
-
export function getFirebaseFunctions(): Functions {
|
|
132
|
+
export function getFirebaseFunctions(): Functions | null {
|
|
133
|
+
if (!app) {
|
|
134
|
+
console.warn('Firebase not initialized. Call initializeFirebase(config) first.')
|
|
135
|
+
return null
|
|
136
|
+
}
|
|
97
137
|
if (!functions) {
|
|
98
|
-
functions = getFunctions(getFirebaseApp())
|
|
138
|
+
functions = getFunctions(getFirebaseApp()!)
|
|
99
139
|
}
|
|
100
140
|
return functions
|
|
101
141
|
}
|
|
102
142
|
|
|
103
143
|
/**
|
|
104
144
|
* Get Firebase Analytics instance
|
|
145
|
+
* @returns Analytics instance or null (not available in SSR or not initialized)
|
|
105
146
|
*/
|
|
106
147
|
export function getFirebaseAnalytics(): Analytics | null {
|
|
148
|
+
if (!app) {
|
|
149
|
+
console.warn('Firebase not initialized. Call initializeFirebase(config) first.')
|
|
150
|
+
return null
|
|
151
|
+
}
|
|
107
152
|
if (!analytics && typeof window !== 'undefined') {
|
|
108
|
-
analytics = getAnalytics(getFirebaseApp())
|
|
153
|
+
analytics = getAnalytics(getFirebaseApp()!)
|
|
109
154
|
}
|
|
110
155
|
return analytics
|
|
111
156
|
}
|
|
112
157
|
|
|
113
158
|
/**
|
|
114
159
|
* Firebase Instances
|
|
115
|
-
* All Firebase service instances
|
|
160
|
+
* All Firebase service instances (may be null if not initialized)
|
|
116
161
|
*/
|
|
117
162
|
export interface FirebaseInstances {
|
|
118
163
|
app: FirebaseApp
|
|
119
|
-
auth: Auth
|
|
120
|
-
db: Firestore
|
|
121
|
-
storage: FirebaseStorage
|
|
122
|
-
functions: Functions
|
|
164
|
+
auth: Auth | null
|
|
165
|
+
db: Firestore | null
|
|
166
|
+
storage: FirebaseStorage | null
|
|
167
|
+
functions: Functions | null
|
|
123
168
|
analytics: Analytics | null
|
|
124
169
|
}
|
|
125
170
|
|
|
126
171
|
/**
|
|
127
172
|
* Get all Firebase instances
|
|
173
|
+
* @returns FirebaseInstances or null if not initialized
|
|
128
174
|
*/
|
|
129
|
-
export function getFirebaseInstances(): FirebaseInstances {
|
|
175
|
+
export function getFirebaseInstances(): FirebaseInstances | null {
|
|
176
|
+
const app = getFirebaseApp()
|
|
177
|
+
if (!app) {
|
|
178
|
+
return null
|
|
179
|
+
}
|
|
130
180
|
return {
|
|
131
|
-
app
|
|
132
|
-
auth: getFirebaseAuth()
|
|
133
|
-
db: getFirebaseDB()
|
|
134
|
-
storage: getFirebaseStorage()
|
|
135
|
-
functions: getFirebaseFunctions()
|
|
181
|
+
app,
|
|
182
|
+
auth: getFirebaseAuth()!,
|
|
183
|
+
db: getFirebaseDB()!,
|
|
184
|
+
storage: getFirebaseStorage()!,
|
|
185
|
+
functions: getFirebaseFunctions()!,
|
|
136
186
|
analytics: getFirebaseAnalytics(),
|
|
137
187
|
}
|
|
138
188
|
}
|
|
139
189
|
|
|
140
|
-
|
|
141
|
-
|
|
190
|
+
/**
|
|
191
|
+
* Check if Firebase is initialized
|
|
192
|
+
*/
|
|
193
|
+
export function isFirebaseInitialized(): boolean {
|
|
194
|
+
return app !== null
|
|
195
|
+
}
|
|
@@ -23,7 +23,11 @@ import { createRepositoryError, RepositoryErrorCode } from '../../domain/errors/
|
|
|
23
23
|
|
|
24
24
|
export class FirestoreAdapter implements IUserRepository {
|
|
25
25
|
private get db() {
|
|
26
|
-
|
|
26
|
+
const db = getFirebaseDB()
|
|
27
|
+
if (!db) {
|
|
28
|
+
throw new Error('Firestore not initialized. Call initializeFirebase() first.')
|
|
29
|
+
}
|
|
30
|
+
return db
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
private readonly USERS_COLLECTION = 'users'
|
|
@@ -26,7 +26,11 @@ import { createRepositoryError, RepositoryErrorCode } from '../../domain/errors/
|
|
|
26
26
|
|
|
27
27
|
export class StorageAdapter implements IFileRepository {
|
|
28
28
|
private get storage() {
|
|
29
|
-
|
|
29
|
+
const storage = getFirebaseStorage()
|
|
30
|
+
if (!storage) {
|
|
31
|
+
throw new Error('Firebase Storage not initialized. Call initializeFirebase() first.')
|
|
32
|
+
}
|
|
33
|
+
return storage
|
|
30
34
|
}
|
|
31
35
|
|
|
32
36
|
// Upload Methods
|