@umituz/react-native-firebase 2.4.96 → 2.4.100
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 +1 -1
- package/src/domains/auth/domain/value-objects/FirebaseAuthConfig.ts +1 -1
- package/src/domains/auth/infrastructure/config/initializers/FirebaseAuthInitializer.ts +5 -41
- package/src/domains/firestore/index.ts +2 -11
- package/src/domains/firestore/infrastructure/config/initializers/FirebaseFirestoreInitializer.ts +4 -255
- package/src/index.ts +1 -1
- package/src/shared/infrastructure/config/clients/FirebaseClientSingleton.ts +1 -1
- package/src/shared/infrastructure/config/services/FirebaseInitializationService.ts +1 -1
- package/src/shared/infrastructure/config/state/FirebaseClientState.ts +1 -1
- package/src/shared/infrastructure/config/initializers/FirebaseAppInitializer.ts +0 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-firebase",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.100",
|
|
4
4
|
"description": "Unified Firebase package for React Native apps - Auth and Firestore services using Firebase JS SDK (no native modules).",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
@@ -21,7 +21,7 @@ export interface FirebaseAuthConfig {
|
|
|
21
21
|
|
|
22
22
|
/**
|
|
23
23
|
* Auth state persistence type
|
|
24
|
-
* - 'local': Persist across
|
|
24
|
+
* - 'local': Persist across app restarts (default)
|
|
25
25
|
* - 'session': Persist only for current session
|
|
26
26
|
* - 'none': No persistence
|
|
27
27
|
*/
|
|
@@ -1,15 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Firebase Auth Initializer
|
|
3
|
-
*
|
|
4
|
-
* Single Responsibility: Initialize Firebase Auth instance
|
|
5
|
-
* Platform-agnostic: Works on all platforms (Web, iOS, Android)
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
1
|
import {
|
|
9
2
|
initializeAuth,
|
|
10
3
|
getAuth,
|
|
11
4
|
// @ts-expect-error: getReactNativePersistence exists in the React Native bundle but missing from type definitions
|
|
12
|
-
// See: https://github.com/firebase/firebase-js-sdk/issues/9316
|
|
13
5
|
getReactNativePersistence,
|
|
14
6
|
} from 'firebase/auth';
|
|
15
7
|
import type { Auth } from 'firebase/auth';
|
|
@@ -17,40 +9,8 @@ import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
|
17
9
|
import type { FirebaseApp } from 'firebase/app';
|
|
18
10
|
import type { FirebaseAuthConfig } from '../../../domain/value-objects/FirebaseAuthConfig';
|
|
19
11
|
|
|
20
|
-
/**
|
|
21
|
-
* Initializes Firebase Auth
|
|
22
|
-
* Platform-agnostic: Works on all platforms (Web, iOS, Android)
|
|
23
|
-
*/
|
|
24
12
|
export class FirebaseAuthInitializer {
|
|
25
|
-
/**
|
|
26
|
-
* Initialize Firebase Auth with persistence support
|
|
27
|
-
*/
|
|
28
13
|
static initialize(app: FirebaseApp, config?: FirebaseAuthConfig): Auth | null {
|
|
29
|
-
try {
|
|
30
|
-
const auth = this.initializeWithPersistence(app, config);
|
|
31
|
-
return auth;
|
|
32
|
-
} catch (error: unknown) {
|
|
33
|
-
return this.handleInitializationError(error, app);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
private static handleInitializationError(error: unknown, app: FirebaseApp): Auth | null {
|
|
38
|
-
// Any initialization error: try to get existing auth instance
|
|
39
|
-
return this.getExistingAuth(app);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
private static getExistingAuth(app: FirebaseApp): Auth | null {
|
|
43
|
-
try {
|
|
44
|
-
return getAuth(app);
|
|
45
|
-
} catch {
|
|
46
|
-
return null;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
private static initializeWithPersistence(
|
|
51
|
-
app: FirebaseApp,
|
|
52
|
-
config?: FirebaseAuthConfig
|
|
53
|
-
): Auth | null {
|
|
54
14
|
try {
|
|
55
15
|
const storage = config?.authStorage || {
|
|
56
16
|
getItem: (key: string) => AsyncStorage.getItem(key),
|
|
@@ -62,7 +22,11 @@ export class FirebaseAuthInitializer {
|
|
|
62
22
|
persistence: getReactNativePersistence(storage),
|
|
63
23
|
});
|
|
64
24
|
} catch {
|
|
65
|
-
|
|
25
|
+
try {
|
|
26
|
+
return getAuth(app);
|
|
27
|
+
} catch {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
66
30
|
}
|
|
67
31
|
}
|
|
68
32
|
}
|
|
@@ -158,14 +158,5 @@ export type { UseFirestoreMutationOptions } from './presentation/hooks/useFirest
|
|
|
158
158
|
export type { UseFirestoreSnapshotOptions } from './presentation/hooks/useFirestoreSnapshot';
|
|
159
159
|
export type { UseSmartFirestoreSnapshotOptions, BackgroundStrategy } from './presentation/hooks/useSmartFirestoreSnapshot';
|
|
160
160
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
CollectionReference,
|
|
164
|
-
QueryDocumentSnapshot,
|
|
165
|
-
DocumentData,
|
|
166
|
-
Transaction,
|
|
167
|
-
DocumentReference,
|
|
168
|
-
WriteBatch,
|
|
169
|
-
DocumentSnapshot,
|
|
170
|
-
QuerySnapshot,
|
|
171
|
-
} from 'firebase/firestore';
|
|
161
|
+
// Firebase types are available from the 'firebase' package directly
|
|
162
|
+
// Import them in your app: import { Timestamp } from 'firebase/firestore';
|
package/src/domains/firestore/infrastructure/config/initializers/FirebaseFirestoreInitializer.ts
CHANGED
|
@@ -1,264 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
* Firebase Firestore Initializer (Enhanced)
|
|
3
|
-
*
|
|
4
|
-
* Single Responsibility: Initialize Firestore instance with optimal caching
|
|
5
|
-
*
|
|
6
|
-
* OPTIMIZATIONS:
|
|
7
|
-
* - Web: Persistent IndexedDB cache (survives restarts) with configurable size
|
|
8
|
-
* - React Native: Memory cache (platform limitation)
|
|
9
|
-
* - Configurable cache size limits (10 MB default for persistent cache)
|
|
10
|
-
* - Platform-aware cache strategy
|
|
11
|
-
*
|
|
12
|
-
* COST SAVINGS: ~90% reduction in network reads through persistent caching
|
|
13
|
-
*
|
|
14
|
-
* NOTE: As of Firebase v10+, cacheSizeBytes must be specified within the cache
|
|
15
|
-
* configuration object (e.g., persistentLocalCache({ cacheSizeBytes })) rather than
|
|
16
|
-
* as a separate Firestore setting. Memory cache doesn't support custom sizes.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
import {
|
|
20
|
-
getFirestore,
|
|
21
|
-
initializeFirestore,
|
|
22
|
-
memoryLocalCache,
|
|
23
|
-
persistentLocalCache,
|
|
24
|
-
type FirestoreSettings,
|
|
25
|
-
} from 'firebase/firestore';
|
|
1
|
+
import { getFirestore, initializeFirestore, memoryLocalCache } from 'firebase/firestore';
|
|
26
2
|
import type { Firestore } from 'firebase/firestore';
|
|
27
3
|
import type { FirebaseApp } from 'firebase/app';
|
|
28
4
|
|
|
29
|
-
/**
|
|
30
|
-
* Cache configuration options
|
|
31
|
-
*/
|
|
32
|
-
export interface FirestoreCacheConfig {
|
|
33
|
-
/** Cache size in bytes (default: 10 MB) */
|
|
34
|
-
cacheSizeBytes?: number;
|
|
35
|
-
/** Enable persistent cache for web (default: true) */
|
|
36
|
-
enablePersistentCache?: boolean;
|
|
37
|
-
/** Force memory-only cache (useful for testing) */
|
|
38
|
-
forceMemoryCache?: boolean;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Default cache configuration
|
|
43
|
-
* Optimized for cost savings while maintaining performance
|
|
44
|
-
*/
|
|
45
|
-
const DEFAULT_CACHE_CONFIG: Required<FirestoreCacheConfig> = {
|
|
46
|
-
cacheSizeBytes: 10 * 1024 * 1024, // 10 MB
|
|
47
|
-
enablePersistentCache: true,
|
|
48
|
-
forceMemoryCache: false,
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Platform detection utilities
|
|
53
|
-
*/
|
|
54
|
-
const Platform = {
|
|
55
|
-
isWeb(): boolean {
|
|
56
|
-
return typeof window !== 'undefined' && typeof window.indexedDB !== 'undefined';
|
|
57
|
-
},
|
|
58
|
-
|
|
59
|
-
isReactNative(): boolean {
|
|
60
|
-
return typeof navigator !== 'undefined' && navigator.product === 'ReactNative';
|
|
61
|
-
},
|
|
62
|
-
|
|
63
|
-
isNode(): boolean {
|
|
64
|
-
return typeof process !== 'undefined' && process.versions?.node !== undefined;
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Creates persistent cache configuration for web platforms
|
|
70
|
-
* Uses IndexedDB to cache data across browser sessions
|
|
71
|
-
*/
|
|
72
|
-
function createPersistentCacheConfig(config: Required<FirestoreCacheConfig>): FirestoreSettings {
|
|
73
|
-
try {
|
|
74
|
-
// Create persistent cache with IndexedDB
|
|
75
|
-
// Note: cacheSizeBytes must be specified inside the cache object, not as a separate setting
|
|
76
|
-
const cacheConfig = persistentLocalCache({
|
|
77
|
-
cacheSizeBytes: config.cacheSizeBytes,
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
return {
|
|
81
|
-
localCache: cacheConfig,
|
|
82
|
-
};
|
|
83
|
-
} catch (error) {
|
|
84
|
-
// If persistent cache fails, fall back to memory cache
|
|
85
|
-
if (__DEV__) {
|
|
86
|
-
console.warn('[Firestore] Persistent cache failed, using memory cache:', error);
|
|
87
|
-
}
|
|
88
|
-
return createMemoryCacheConfig(config);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Creates optimized memory cache configuration for React Native
|
|
94
|
-
* Uses memory cache for platforms without IndexedDB support
|
|
95
|
-
*/
|
|
96
|
-
function createMemoryCacheConfig(config: Required<FirestoreCacheConfig>): FirestoreSettings {
|
|
97
|
-
// Memory cache - doesn't support cacheSizeBytes parameter
|
|
98
|
-
// Note: memoryLocalCache() doesn't accept any parameters
|
|
99
|
-
const cacheConfig = memoryLocalCache();
|
|
100
|
-
|
|
101
|
-
return {
|
|
102
|
-
localCache: cacheConfig,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Initializes Firestore with optimal caching strategy based on platform
|
|
108
|
-
*
|
|
109
|
-
* @param app - Firebase app instance
|
|
110
|
-
* @param config - Cache configuration options
|
|
111
|
-
* @returns Firestore instance
|
|
112
|
-
*
|
|
113
|
-
* @example
|
|
114
|
-
* ```typescript
|
|
115
|
-
* // Default configuration (recommended)
|
|
116
|
-
* const db = FirebaseFirestoreInitializer.initialize(app);
|
|
117
|
-
*
|
|
118
|
-
* // Custom cache size (20 MB)
|
|
119
|
-
* const db = FirebaseFirestoreInitializer.initialize(app, {
|
|
120
|
-
* cacheSizeBytes: 20 * 1024 * 1024,
|
|
121
|
-
* });
|
|
122
|
-
*
|
|
123
|
-
* // Force memory cache (testing)
|
|
124
|
-
* const db = FirebaseFirestoreInitializer.initialize(app, {
|
|
125
|
-
* forceMemoryCache: true,
|
|
126
|
-
* });
|
|
127
|
-
* ```
|
|
128
|
-
*/
|
|
129
5
|
export class FirebaseFirestoreInitializer {
|
|
130
|
-
|
|
131
|
-
* Initialize Firestore with platform-optimized caching
|
|
132
|
-
*
|
|
133
|
-
* Platform Strategy:
|
|
134
|
-
* - Web: Persistent IndexedDB cache (survives restarts, 90% cost savings)
|
|
135
|
-
* - React Native: Memory cache
|
|
136
|
-
* - Node.js: Memory cache for server-side rendering
|
|
137
|
-
*/
|
|
138
|
-
static initialize(
|
|
139
|
-
app: FirebaseApp,
|
|
140
|
-
config: FirestoreCacheConfig = {}
|
|
141
|
-
): Firestore {
|
|
142
|
-
const finalConfig = { ...DEFAULT_CACHE_CONFIG, ...config };
|
|
143
|
-
|
|
6
|
+
static initialize(app: FirebaseApp): Firestore {
|
|
144
7
|
try {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
try {
|
|
148
|
-
return initializeFirestore(app, createPersistentCacheConfig(finalConfig));
|
|
149
|
-
} catch (error) {
|
|
150
|
-
// IndexedDB may be disabled in private browsing mode
|
|
151
|
-
// Fall back to memory cache
|
|
152
|
-
if (__DEV__) {
|
|
153
|
-
console.warn('[Firestore] Persistent cache failed, using memory cache:', error);
|
|
154
|
-
}
|
|
155
|
-
return initializeFirestore(app, createMemoryCacheConfig(finalConfig));
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
// React Native with memory cache
|
|
160
|
-
// Note: React Native doesn't support IndexedDB, use memory cache
|
|
161
|
-
if (Platform.isReactNative()) {
|
|
162
|
-
return initializeFirestore(app, createMemoryCacheConfig(finalConfig));
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Node.js / Server-side with memory cache
|
|
166
|
-
if (Platform.isNode()) {
|
|
167
|
-
return initializeFirestore(app, createMemoryCacheConfig(finalConfig));
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Fallback: Try persistent cache, fall back to memory
|
|
171
|
-
return initializeFirestore(app, createPersistentCacheConfig(finalConfig));
|
|
172
|
-
} catch (error) {
|
|
173
|
-
// If initialization fails, get existing instance
|
|
174
|
-
// This handles cases where Firestore is already initialized
|
|
175
|
-
if (__DEV__) {
|
|
176
|
-
console.warn('[Firestore] Initialization failed, getting existing instance:', error);
|
|
177
|
-
}
|
|
8
|
+
return initializeFirestore(app, { localCache: memoryLocalCache() });
|
|
9
|
+
} catch {
|
|
178
10
|
return getFirestore(app);
|
|
179
11
|
}
|
|
180
12
|
}
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* Initialize Firestore with memory-only cache
|
|
184
|
-
* Useful for testing or sensitive data that shouldn't be persisted
|
|
185
|
-
*/
|
|
186
|
-
static initializeWithMemoryCache(
|
|
187
|
-
app: FirebaseApp,
|
|
188
|
-
config: Omit<FirestoreCacheConfig, 'enablePersistentCache' | 'forceMemoryCache'> = {}
|
|
189
|
-
): Firestore {
|
|
190
|
-
return this.initialize(app, {
|
|
191
|
-
...config,
|
|
192
|
-
forceMemoryCache: true,
|
|
193
|
-
enablePersistentCache: false,
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Check if persistent cache is available on current platform
|
|
199
|
-
*/
|
|
200
|
-
static isPersistentCacheAvailable(): boolean {
|
|
201
|
-
return Platform.isWeb() && typeof window.indexedDB !== 'undefined';
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
/**
|
|
205
|
-
* Get current cache size in bytes
|
|
206
|
-
* Note: This is an estimate, actual size may vary
|
|
207
|
-
*/
|
|
208
|
-
static getEstimatedCacheSize(config: FirestoreCacheConfig = {}): number {
|
|
209
|
-
return config.cacheSizeBytes ?? DEFAULT_CACHE_CONFIG.cacheSizeBytes;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
/**
|
|
213
|
-
* Clear all Firestore caches (useful for logout or data reset)
|
|
214
|
-
* WARNING: This will clear all cached data and force re-fetch
|
|
215
|
-
*/
|
|
216
|
-
static async clearPersistentCache(app: FirebaseApp): Promise<void> {
|
|
217
|
-
try {
|
|
218
|
-
const db = getFirestore(app);
|
|
219
|
-
await (db as any).clearPersistentCache();
|
|
220
|
-
if (__DEV__) {
|
|
221
|
-
console.log('[Firestore] Persistent cache cleared');
|
|
222
|
-
}
|
|
223
|
-
} catch (error) {
|
|
224
|
-
if (__DEV__) {
|
|
225
|
-
console.warn('[Firestore] Failed to clear persistent cache:', error);
|
|
226
|
-
}
|
|
227
|
-
throw error;
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Cache statistics interface
|
|
234
|
-
*/
|
|
235
|
-
export interface CacheStatistics {
|
|
236
|
-
/** Platform type */
|
|
237
|
-
platform: 'web' | 'react-native' | 'node' | 'unknown';
|
|
238
|
-
/** Persistent cache available */
|
|
239
|
-
persistentCacheAvailable: boolean;
|
|
240
|
-
/** Current cache size limit */
|
|
241
|
-
cacheSizeBytes: number;
|
|
242
|
-
/** Estimated cache usage percentage */
|
|
243
|
-
estimatedCacheUsage: number;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/**
|
|
247
|
-
* Get cache statistics for monitoring and debugging
|
|
248
|
-
*/
|
|
249
|
-
export function getCacheStatistics(): CacheStatistics {
|
|
250
|
-
const platform = Platform.isWeb()
|
|
251
|
-
? 'web'
|
|
252
|
-
: Platform.isReactNative()
|
|
253
|
-
? 'react-native'
|
|
254
|
-
: Platform.isNode()
|
|
255
|
-
? 'node'
|
|
256
|
-
: 'unknown';
|
|
257
|
-
|
|
258
|
-
return {
|
|
259
|
-
platform,
|
|
260
|
-
persistentCacheAvailable: FirebaseFirestoreInitializer.isPersistentCacheAvailable(),
|
|
261
|
-
cacheSizeBytes: FirebaseFirestoreInitializer.getEstimatedCacheSize(),
|
|
262
|
-
estimatedCacheUsage: 0, // Firestore doesn't expose actual cache size
|
|
263
|
-
};
|
|
264
13
|
}
|
package/src/index.ts
CHANGED
|
@@ -32,7 +32,7 @@ export type {
|
|
|
32
32
|
ServiceInitializationResult,
|
|
33
33
|
} from "./shared/infrastructure/config/services/FirebaseInitializationService";
|
|
34
34
|
|
|
35
|
-
export type { FirebaseApp } from
|
|
35
|
+
export type { FirebaseApp } from 'firebase/app';
|
|
36
36
|
|
|
37
37
|
// Type Guards
|
|
38
38
|
export {
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
import type { FirebaseConfig } from '../../../domain/value-objects/FirebaseConfig';
|
|
7
7
|
import type { IFirebaseClient } from '../../../../application/ports/IFirebaseClient';
|
|
8
|
-
import type { FirebaseApp } from '
|
|
8
|
+
import type { FirebaseApp } from 'firebase/app';
|
|
9
9
|
import { FirebaseClientState } from '../state/FirebaseClientState';
|
|
10
10
|
import { FirebaseInitializationOrchestrator } from '../orchestrators/FirebaseInitializationOrchestrator';
|
|
11
11
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import type { FirebaseConfig } from '../../../domain/value-objects/FirebaseConfig';
|
|
7
|
-
import type { FirebaseApp } from '
|
|
7
|
+
import type { FirebaseApp } from 'firebase/app';
|
|
8
8
|
import { FirebaseClientSingleton } from '../clients/FirebaseClientSingleton';
|
|
9
9
|
import { loadFirebaseConfig } from '../FirebaseConfigLoader';
|
|
10
10
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Uses generic ClientStateManager for shared functionality
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type { FirebaseApp } from '
|
|
9
|
+
import type { FirebaseApp } from 'firebase/app';
|
|
10
10
|
import { ClientStateManager } from '../base/ClientStateManager';
|
|
11
11
|
|
|
12
12
|
export class FirebaseClientState extends ClientStateManager<FirebaseApp> {
|