@umituz/react-native-firebase 1.4.0 → 1.5.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 (43) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +0 -0
  3. package/lib/application/ports/IFirebaseClient.d.ts +37 -0
  4. package/lib/application/ports/IFirebaseClient.d.ts.map +1 -0
  5. package/lib/application/ports/IFirebaseClient.js +8 -0
  6. package/lib/application/ports/IFirebaseClient.js.map +1 -0
  7. package/lib/domain/errors/FirebaseError.d.ts +28 -0
  8. package/lib/domain/errors/FirebaseError.d.ts.map +1 -0
  9. package/lib/domain/errors/FirebaseError.js +46 -0
  10. package/lib/domain/errors/FirebaseError.js.map +1 -0
  11. package/lib/domain/value-objects/FirebaseConfig.d.ts +36 -0
  12. package/lib/domain/value-objects/FirebaseConfig.d.ts.map +1 -0
  13. package/lib/domain/value-objects/FirebaseConfig.js +8 -0
  14. package/lib/domain/value-objects/FirebaseConfig.js.map +1 -0
  15. package/lib/index.d.ts +26 -0
  16. package/lib/index.d.ts.map +1 -0
  17. package/lib/index.js +29 -0
  18. package/lib/index.js.map +1 -0
  19. package/lib/infrastructure/config/FirebaseClient.d.ts +145 -0
  20. package/lib/infrastructure/config/FirebaseClient.d.ts.map +1 -0
  21. package/lib/infrastructure/config/FirebaseClient.js +335 -0
  22. package/lib/infrastructure/config/FirebaseClient.js.map +1 -0
  23. package/lib/infrastructure/config/FirebaseConfigLoader.d.ts +16 -0
  24. package/lib/infrastructure/config/FirebaseConfigLoader.d.ts.map +1 -0
  25. package/lib/infrastructure/config/FirebaseConfigLoader.js +131 -0
  26. package/lib/infrastructure/config/FirebaseConfigLoader.js.map +1 -0
  27. package/lib/infrastructure/config/initializers/FirebaseAppInitializer.d.ts +17 -0
  28. package/lib/infrastructure/config/initializers/FirebaseAppInitializer.d.ts.map +1 -0
  29. package/lib/infrastructure/config/initializers/FirebaseAppInitializer.js +83 -0
  30. package/lib/infrastructure/config/initializers/FirebaseAppInitializer.js.map +1 -0
  31. package/lib/infrastructure/config/validators/FirebaseConfigValidator.d.ts +18 -0
  32. package/lib/infrastructure/config/validators/FirebaseConfigValidator.d.ts.map +1 -0
  33. package/lib/infrastructure/config/validators/FirebaseConfigValidator.js +62 -0
  34. package/lib/infrastructure/config/validators/FirebaseConfigValidator.js.map +1 -0
  35. package/package.json +19 -4
  36. package/src/application/ports/IFirebaseClient.ts +1 -1
  37. package/src/domain/errors/FirebaseError.ts +0 -0
  38. package/src/domain/value-objects/FirebaseConfig.ts +0 -0
  39. package/src/index.ts +0 -0
  40. package/src/infrastructure/config/FirebaseClient.ts +222 -92
  41. package/src/infrastructure/config/FirebaseConfigLoader.ts +140 -45
  42. package/src/infrastructure/config/initializers/FirebaseAppInitializer.ts +67 -27
  43. package/src/infrastructure/config/validators/FirebaseConfigValidator.ts +58 -25
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Firebase Configuration Validator
3
+ *
4
+ * Single Responsibility: Validates Firebase configuration
5
+ */
6
+ import { FirebaseConfigurationError } from '../../../domain/errors/FirebaseError';
7
+ /**
8
+ * Required field validation rule
9
+ */
10
+ class RequiredFieldRule {
11
+ constructor(fieldName, getter) {
12
+ this.fieldName = fieldName;
13
+ this.getter = getter;
14
+ }
15
+ validate(config) {
16
+ const value = this.getter(config);
17
+ if (!value || typeof value !== 'string') {
18
+ throw new FirebaseConfigurationError(`Firebase ${this.fieldName} is required and must be a string`);
19
+ }
20
+ if (value.trim().length === 0) {
21
+ throw new FirebaseConfigurationError(`Firebase ${this.fieldName} cannot be empty`);
22
+ }
23
+ }
24
+ }
25
+ /**
26
+ * Placeholder validation rule
27
+ */
28
+ class PlaceholderRule {
29
+ constructor(fieldName, getter, placeholder) {
30
+ this.fieldName = fieldName;
31
+ this.getter = getter;
32
+ this.placeholder = placeholder;
33
+ }
34
+ validate(config) {
35
+ const value = this.getter(config);
36
+ if (value && value.includes(this.placeholder)) {
37
+ throw new FirebaseConfigurationError(`Please replace placeholder values with actual Firebase credentials for ${this.fieldName}`);
38
+ }
39
+ }
40
+ }
41
+ /**
42
+ * Firebase Configuration Validator
43
+ */
44
+ export class FirebaseConfigValidator {
45
+ /**
46
+ * Validate Firebase configuration
47
+ * @throws {FirebaseConfigurationError} If configuration is invalid
48
+ */
49
+ static validate(config) {
50
+ for (const rule of this.rules) {
51
+ rule.validate(config);
52
+ }
53
+ }
54
+ }
55
+ FirebaseConfigValidator.rules = [
56
+ new RequiredFieldRule('API Key', config => config.apiKey),
57
+ new RequiredFieldRule('Auth Domain', config => config.authDomain),
58
+ new RequiredFieldRule('Project ID', config => config.projectId),
59
+ new PlaceholderRule('API Key', config => config.apiKey, 'your_firebase_api_key'),
60
+ new PlaceholderRule('Project ID', config => config.projectId, 'your-project-id'),
61
+ ];
62
+ //# sourceMappingURL=FirebaseConfigValidator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FirebaseConfigValidator.js","sourceRoot":"","sources":["../../../../src/infrastructure/config/validators/FirebaseConfigValidator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AASlF;;GAEG;AACH,MAAM,iBAAiB;IACrB,YACU,SAAiB,EACjB,MAAsD;QADtD,cAAS,GAAT,SAAS,CAAQ;QACjB,WAAM,GAAN,MAAM,CAAgD;IAC7D,CAAC;IAEJ,QAAQ,CAAC,MAAsB;QAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAElC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACxC,MAAM,IAAI,0BAA0B,CAClC,YAAY,IAAI,CAAC,SAAS,mCAAmC,CAC9D,CAAC;QACJ,CAAC;QAED,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,0BAA0B,CAAC,YAAY,IAAI,CAAC,SAAS,kBAAkB,CAAC,CAAC;QACrF,CAAC;IACH,CAAC;CACF;AAED;;GAEG;AACH,MAAM,eAAe;IACnB,YACU,SAAiB,EACjB,MAAsD,EACtD,WAAmB;QAFnB,cAAS,GAAT,SAAS,CAAQ;QACjB,WAAM,GAAN,MAAM,CAAgD;QACtD,gBAAW,GAAX,WAAW,CAAQ;IAC1B,CAAC;IAEJ,QAAQ,CAAC,MAAsB;QAC7B,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAElC,IAAI,KAAK,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YAC9C,MAAM,IAAI,0BAA0B,CAClC,0EAA0E,IAAI,CAAC,SAAS,EAAE,CAC3F,CAAC;QACJ,CAAC;IACH,CAAC;CACF;AAED;;GAEG;AACH,MAAM,OAAO,uBAAuB;IASlC;;;OAGG;IACH,MAAM,CAAC,QAAQ,CAAC,MAAsB;QACpC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;;AAhBc,6BAAK,GAAqB;IACvC,IAAI,iBAAiB,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC;IACzD,IAAI,iBAAiB,CAAC,aAAa,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC;IACjE,IAAI,iBAAiB,CAAC,YAAY,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC;IAC/D,IAAI,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,uBAAuB,CAAC;IAChF,IAAI,eAAe,CAAC,YAAY,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,iBAAiB,CAAC;CACjF,CAAC"}
package/package.json CHANGED
@@ -1,12 +1,17 @@
1
1
  {
2
2
  "name": "@umituz/react-native-firebase",
3
- "version": "1.4.0",
3
+ "version": "1.5.1",
4
4
  "description": "Firebase core package for React Native apps - Centralized initialization for all Firebase services (App, Auth, Analytics, Crashlytics). Use dedicated packages for service-specific operations.",
5
- "main": "./src/index.ts",
6
- "types": "./src/index.ts",
5
+ "main": "./lib/index.js",
6
+ "types": "./lib/index.d.ts",
7
7
  "scripts": {
8
+ "build": "tsc",
8
9
  "typecheck": "tsc --noEmit",
9
10
  "lint": "tsc --noEmit",
11
+ "test": "jest",
12
+ "test:watch": "jest --watch",
13
+ "test:coverage": "jest --coverage",
14
+ "prepublishOnly": "npm run build",
10
15
  "version:patch": "npm version patch -m 'chore: release v%s'",
11
16
  "version:minor": "npm version minor -m 'chore: release v%s'",
12
17
  "version:major": "npm version major -m 'chore: release v%s'"
@@ -31,17 +36,27 @@
31
36
  "react-native": ">=0.74.0"
32
37
  },
33
38
  "devDependencies": {
39
+ "@types/jest": "^30.0.0",
40
+ "@types/node": "^25.0.1",
34
41
  "@types/react": "^18.2.45",
35
42
  "@types/react-native": "^0.73.0",
43
+ "chalk": "^4.1.2",
44
+ "find-up": "^8.0.0",
36
45
  "firebase": "^11.0.0",
46
+ "jest": "^30.2.0",
47
+ "p-limit": "^7.2.0",
48
+ "p-try": "^3.0.0",
49
+ "path-exists": "^5.0.0",
37
50
  "react": "^18.2.0",
38
51
  "react-native": "^0.74.0",
39
- "typescript": "^5.3.3"
52
+ "ts-jest": "^29.4.6",
53
+ "typescript": "^5.9.3"
40
54
  },
41
55
  "publishConfig": {
42
56
  "access": "public"
43
57
  },
44
58
  "files": [
59
+ "lib",
45
60
  "src",
46
61
  "README.md",
47
62
  "LICENSE"
@@ -5,7 +5,7 @@
5
5
  * Defines the contract for Firebase client operations
6
6
  */
7
7
 
8
- import type { FirebaseApp } from 'firebase/app';
8
+ export type FirebaseApp = any;
9
9
 
10
10
  /**
11
11
  * Firebase Client Interface
File without changes
File without changes
package/src/index.ts CHANGED
File without changes
@@ -13,104 +13,208 @@
13
13
  * - Dependency Inversion: Depends on abstractions (interfaces), not concrete implementations
14
14
  */
15
15
 
16
- import type { FirebaseApp } from 'firebase/app';
17
16
  import type { FirebaseConfig } from '../../domain/value-objects/FirebaseConfig';
18
- import { FirebaseInitializationError } from '../../domain/errors/FirebaseError';
19
17
  import type { IFirebaseClient } from '../../application/ports/IFirebaseClient';
20
18
  import { FirebaseConfigValidator } from './validators/FirebaseConfigValidator';
21
19
  import { FirebaseAppInitializer } from './initializers/FirebaseAppInitializer';
22
20
  import { loadFirebaseConfig } from './FirebaseConfigLoader';
23
21
 
22
+ export type FirebaseApp = any;
23
+
24
+ // Development environment check
25
+ declare const __DEV__: boolean;
26
+
24
27
  /**
25
- * Firebase Client Singleton
26
- * Orchestrates Firebase initialization using specialized initializers
28
+ * Firebase Client State Manager
29
+ * Manages the state of Firebase initialization
27
30
  */
28
- class FirebaseClientSingleton implements IFirebaseClient {
29
- private static instance: FirebaseClientSingleton | null = null;
31
+ class FirebaseClientState {
30
32
  private app: FirebaseApp | null = null;
31
33
  private initializationError: string | null = null;
32
34
 
33
- private constructor() {
34
- // Private constructor to enforce singleton pattern
35
+ /**
36
+ * Get the current Firebase app instance
37
+ */
38
+ getApp(): FirebaseApp | null {
39
+ return this.app;
35
40
  }
36
41
 
37
42
  /**
38
- * Get singleton instance
43
+ * Set the Firebase app instance
39
44
  */
40
- static getInstance(): FirebaseClientSingleton {
41
- if (!FirebaseClientSingleton.instance) {
42
- FirebaseClientSingleton.instance = new FirebaseClientSingleton();
43
- }
44
- return FirebaseClientSingleton.instance;
45
+ setApp(app: FirebaseApp | null): void {
46
+ this.app = app;
45
47
  }
46
48
 
47
49
  /**
48
- * Initialize Firebase client with configuration
49
- * Configuration must be provided by the application (not from .env)
50
- *
51
- * @param config - Firebase configuration
52
- * @returns Firebase app instance or null if initialization fails
50
+ * Check if client is initialized
53
51
  */
54
- initialize(config: FirebaseConfig): FirebaseApp | null {
52
+ isInitialized(): boolean {
53
+ return this.app !== null;
54
+ }
55
+
56
+ /**
57
+ * Get initialization error if any
58
+ */
59
+ getInitializationError(): string | null {
60
+ return this.initializationError;
61
+ }
62
+
63
+ /**
64
+ * Set initialization error
65
+ */
66
+ setInitializationError(error: string | null): void {
67
+ this.initializationError = error;
68
+ }
69
+
70
+ /**
71
+ * Reset the client state
72
+ */
73
+ reset(): void {
74
+ this.app = null;
75
+ this.initializationError = null;
76
+ }
77
+ }
78
+
79
+ /**
80
+ * Firebase Initialization Orchestrator
81
+ * Handles the initialization logic
82
+ */
83
+ class FirebaseInitializationOrchestrator {
84
+ /**
85
+ * Initialize Firebase with configuration
86
+ */
87
+ static initialize(
88
+ config: FirebaseConfig,
89
+ state: FirebaseClientState
90
+ ): FirebaseApp | null {
55
91
  // Return existing instance if already initialized
56
- if (this.app) {
57
- return this.app;
92
+ if (state.isInitialized()) {
93
+ if (__DEV__) {
94
+ console.log('[Firebase] Already initialized, returning existing instance');
95
+ }
96
+ return state.getApp();
58
97
  }
59
98
 
60
99
  // Don't retry if initialization already failed
61
- if (this.initializationError) {
100
+ if (state.getInitializationError()) {
101
+ if (__DEV__) {
102
+ console.log('[Firebase] Previous initialization failed, skipping retry');
103
+ }
62
104
  return null;
63
105
  }
64
106
 
65
107
  try {
108
+ if (__DEV__) {
109
+ console.log('[Firebase] Initializing with projectId:', config.projectId);
110
+ }
111
+
66
112
  // Validate configuration
67
113
  FirebaseConfigValidator.validate(config);
68
114
 
69
115
  // Initialize Firebase App
70
- this.app = FirebaseAppInitializer.initialize(config);
116
+ const app = FirebaseAppInitializer.initialize(config);
117
+ state.setApp(app);
118
+
119
+ if (__DEV__) {
120
+ console.log('[Firebase] Successfully initialized');
121
+ }
71
122
 
72
- return this.app;
123
+ return app;
73
124
  } catch (error) {
74
- this.initializationError =
125
+ const errorMessage =
75
126
  error instanceof Error
76
127
  ? error.message
77
128
  : 'Failed to initialize Firebase client';
129
+ state.setInitializationError(errorMessage);
130
+
131
+ if (__DEV__) {
132
+ console.error('[Firebase] Initialization failed:', errorMessage);
133
+ }
134
+
78
135
  return null;
79
136
  }
80
137
  }
81
138
 
82
139
  /**
83
- * Get the Firebase app instance
84
- * Auto-initializes from Constants/environment if not already initialized
85
- * Returns null if config is not available (offline mode)
86
- * @returns Firebase app instance or null if not initialized
140
+ * Auto-initialize Firebase from environment
87
141
  */
88
- getApp(): FirebaseApp | null {
89
- // Auto-initialize if not already initialized
90
- if (!this.app && !this.initializationError) {
91
- const autoConfig = loadFirebaseConfig();
92
- if (autoConfig) {
93
- this.initialize(autoConfig);
142
+ static autoInitialize(state: FirebaseClientState): FirebaseApp | null {
143
+ if (state.isInitialized() || state.getInitializationError()) {
144
+ return state.getApp();
145
+ }
146
+
147
+ const autoConfig = loadFirebaseConfig();
148
+ if (autoConfig) {
149
+ if (__DEV__) {
150
+ console.log('[Firebase] Auto-initializing with environment config');
94
151
  }
152
+ return this.initialize(autoConfig, state);
153
+ }
154
+
155
+ if (__DEV__) {
156
+ console.log('[Firebase] No configuration found for auto-initialization');
157
+ }
158
+
159
+ return null;
160
+ }
161
+ }
162
+
163
+ /**
164
+ * Firebase Client Singleton
165
+ * Orchestrates Firebase initialization using specialized initializers
166
+ */
167
+ class FirebaseClientSingleton implements IFirebaseClient {
168
+ private static instance: FirebaseClientSingleton | null = null;
169
+ private state: FirebaseClientState;
170
+
171
+ private constructor() {
172
+ this.state = new FirebaseClientState();
173
+ }
174
+
175
+ /**
176
+ * Get singleton instance
177
+ */
178
+ static getInstance(): FirebaseClientSingleton {
179
+ if (!FirebaseClientSingleton.instance) {
180
+ FirebaseClientSingleton.instance = new FirebaseClientSingleton();
95
181
  }
182
+ return FirebaseClientSingleton.instance;
183
+ }
96
184
 
97
- // Return null if not initialized (offline mode - no error)
98
- return this.app || null;
185
+ /**
186
+ * Initialize Firebase client with configuration
187
+ * Configuration must be provided by the application (not from .env)
188
+ *
189
+ * @param config - Firebase configuration
190
+ * @returns Firebase app instance or null if initialization fails
191
+ */
192
+ initialize(config: FirebaseConfig): FirebaseApp | null {
193
+ return FirebaseInitializationOrchestrator.initialize(config, this.state);
99
194
  }
100
195
 
196
+ /**
197
+ * Get the Firebase app instance
198
+ * Auto-initializes from Constants/environment if not already initialized
199
+ * Returns null if config is not available (offline mode - no error)
200
+ * @returns Firebase app instance or null if not initialized
201
+ */
202
+ getApp(): FirebaseApp | null {
203
+ return FirebaseInitializationOrchestrator.autoInitialize(this.state);
204
+ }
101
205
 
102
206
  /**
103
207
  * Check if client is initialized
104
208
  */
105
209
  isInitialized(): boolean {
106
- return this.app !== null;
210
+ return this.state.isInitialized();
107
211
  }
108
212
 
109
213
  /**
110
214
  * Get initialization error if any
111
215
  */
112
216
  getInitializationError(): string | null {
113
- return this.initializationError;
217
+ return this.state.getInitializationError();
114
218
  }
115
219
 
116
220
  /**
@@ -118,8 +222,7 @@ class FirebaseClientSingleton implements IFirebaseClient {
118
222
  * Useful for testing
119
223
  */
120
224
  reset(): void {
121
- this.app = null;
122
- this.initializationError = null;
225
+ this.state.reset();
123
226
  }
124
227
  }
125
228
 
@@ -178,6 +281,79 @@ export function autoInitializeFirebase(): FirebaseApp | null {
178
281
  return null;
179
282
  }
180
283
 
284
+ /**
285
+ * Service initialization result interface
286
+ */
287
+ interface ServiceInitializationResult {
288
+ app: FirebaseApp | null;
289
+ auth: any | null;
290
+ analytics: any | null;
291
+ crashlytics: any | null;
292
+ }
293
+
294
+ /**
295
+ * Service initializer class for better separation of concerns
296
+ */
297
+ class ServiceInitializer {
298
+ /**
299
+ * Initialize optional Firebase service with error handling
300
+ */
301
+ private static initializeService(
302
+ packageName: string,
303
+ initializerName: string,
304
+ isAsync = false
305
+ ): any | null {
306
+ try {
307
+ const serviceModule = require(packageName);
308
+ const service = serviceModule[initializerName];
309
+
310
+ if (isAsync && typeof service.init === 'function') {
311
+ return service;
312
+ }
313
+
314
+ return typeof service === 'function' ? service() : service;
315
+ } catch {
316
+ return null;
317
+ }
318
+ }
319
+
320
+ /**
321
+ * Initialize all optional Firebase services
322
+ */
323
+ static async initializeServices(): Promise<{
324
+ auth: any | null;
325
+ analytics: any | null;
326
+ crashlytics: any | null;
327
+ }> {
328
+ if (__DEV__) {
329
+ console.log('[Firebase] Initializing optional services...');
330
+ }
331
+
332
+ const auth = this.initializeService(
333
+ '@umituz/react-native-firebase-auth',
334
+ 'initializeFirebaseAuth'
335
+ );
336
+
337
+ const analytics = this.initializeService(
338
+ '@umituz/react-native-firebase-analytics',
339
+ 'firebaseAnalyticsService',
340
+ true
341
+ );
342
+
343
+ const crashlytics = this.initializeService(
344
+ '@umituz/react-native-firebase-crashlytics',
345
+ 'firebaseCrashlyticsService',
346
+ true
347
+ );
348
+
349
+ if (__DEV__) {
350
+ console.log('[Firebase] Services initialized - Auth:', !!auth, 'Analytics:', !!analytics, 'Crashlytics:', !!crashlytics);
351
+ }
352
+
353
+ return { auth, analytics, crashlytics };
354
+ }
355
+ }
356
+
181
357
  /**
182
358
  * Initialize all Firebase services (App, Auth, Analytics, Crashlytics)
183
359
  * This is the main entry point for applications - call this once at app startup
@@ -203,22 +379,10 @@ export function autoInitializeFirebase(): FirebaseApp | null {
203
379
  */
204
380
  export async function initializeAllFirebaseServices(
205
381
  config?: FirebaseConfig
206
- ): Promise<{
207
- app: FirebaseApp | null;
208
- auth: any | null;
209
- analytics: any | null;
210
- crashlytics: any | null;
211
- }> {
212
- // 1. Initialize Firebase App
213
- let app: FirebaseApp | null = null;
214
- if (config) {
215
- app = initializeFirebase(config);
216
- } else {
217
- app = autoInitializeFirebase();
218
- }
382
+ ): Promise<ServiceInitializationResult> {
383
+ const app = config ? initializeFirebase(config) : autoInitializeFirebase();
219
384
 
220
385
  if (!app) {
221
- // Firebase App not available - return null for all services
222
386
  return {
223
387
  app: null,
224
388
  auth: null,
@@ -227,37 +391,7 @@ export async function initializeAllFirebaseServices(
227
391
  };
228
392
  }
229
393
 
230
- // 2. Initialize Firebase Auth (if package is available)
231
- let auth: any | null = null;
232
- try {
233
- // eslint-disable-next-line @typescript-eslint/no-require-imports
234
- const { initializeFirebaseAuth } = require('@umituz/react-native-firebase-auth');
235
- auth = initializeFirebaseAuth();
236
- } catch {
237
- // @umituz/react-native-firebase-auth not available
238
- }
239
-
240
- // 3. Initialize Firebase Analytics (if package is available)
241
- let analytics: any | null = null;
242
- try {
243
- // eslint-disable-next-line @typescript-eslint/no-require-imports
244
- const { firebaseAnalyticsService } = require('@umituz/react-native-firebase-analytics');
245
- await firebaseAnalyticsService.init();
246
- analytics = firebaseAnalyticsService;
247
- } catch {
248
- // @umituz/react-native-firebase-analytics not available
249
- }
250
-
251
- // 4. Initialize Firebase Crashlytics (if package is available)
252
- let crashlytics: any | null = null;
253
- try {
254
- // eslint-disable-next-line @typescript-eslint/no-require-imports
255
- const { firebaseCrashlyticsService } = require('@umituz/react-native-firebase-crashlytics');
256
- await firebaseCrashlyticsService.init();
257
- crashlytics = firebaseCrashlyticsService;
258
- } catch {
259
- // @umituz/react-native-firebase-crashlytics not available
260
- }
394
+ const { auth, analytics, crashlytics } = await ServiceInitializer.initializeServices();
261
395
 
262
396
  return {
263
397
  app,
@@ -287,8 +421,4 @@ export function getFirebaseInitializationError(): string | null {
287
421
  */
288
422
  export function resetFirebaseClient(): void {
289
423
  firebaseClient.reset();
290
- }
291
-
292
- // Export types
293
- export type { FirebaseApp } from 'firebase/app';
294
- export type { FirebaseConfig } from '../../domain/value-objects/FirebaseConfig';
424
+ }