@react-native-firebase/firestore 20.3.0 → 20.4.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.
Files changed (28) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/__tests__/firestore.test.ts +292 -1
  3. package/android/src/main/java/io/invertase/firebase/firestore/UniversalFirebaseFirestoreCommon.java +17 -9
  4. package/android/src/main/java/io/invertase/firebase/firestore/UniversalFirebaseFirestoreModule.java +28 -26
  5. package/android/src/reactnative/java/io/invertase/firebase/firestore/ReactNativeFirebaseFirestoreCollectionModule.java +53 -22
  6. package/android/src/reactnative/java/io/invertase/firebase/firestore/ReactNativeFirebaseFirestoreCommon.java +5 -2
  7. package/android/src/reactnative/java/io/invertase/firebase/firestore/ReactNativeFirebaseFirestoreDocumentModule.java +35 -21
  8. package/android/src/reactnative/java/io/invertase/firebase/firestore/ReactNativeFirebaseFirestoreEvent.java +5 -1
  9. package/android/src/reactnative/java/io/invertase/firebase/firestore/ReactNativeFirebaseFirestoreModule.java +48 -16
  10. package/android/src/reactnative/java/io/invertase/firebase/firestore/ReactNativeFirebaseFirestoreQuery.java +3 -1
  11. package/android/src/reactnative/java/io/invertase/firebase/firestore/ReactNativeFirebaseFirestoreSerialize.java +13 -8
  12. package/android/src/reactnative/java/io/invertase/firebase/firestore/ReactNativeFirebaseFirestoreTransactionModule.java +12 -7
  13. package/ios/RNFBFirestore/RNFBFirestoreCollectionModule.m +78 -49
  14. package/ios/RNFBFirestore/RNFBFirestoreCommon.h +6 -2
  15. package/ios/RNFBFirestore/RNFBFirestoreCommon.m +23 -10
  16. package/ios/RNFBFirestore/RNFBFirestoreDocumentModule.m +41 -11
  17. package/ios/RNFBFirestore/RNFBFirestoreModule.m +66 -15
  18. package/ios/RNFBFirestore/RNFBFirestoreSerialize.h +5 -3
  19. package/ios/RNFBFirestore/RNFBFirestoreSerialize.m +17 -10
  20. package/ios/RNFBFirestore/RNFBFirestoreTransactionModule.m +21 -7
  21. package/lib/FirestorePersistentCacheIndexManager.js +34 -0
  22. package/lib/index.d.ts +32 -1
  23. package/lib/index.js +25 -2
  24. package/lib/modular/index.d.ts +52 -0
  25. package/lib/modular/index.js +55 -3
  26. package/lib/version.js +1 -1
  27. package/lib/web/RNFBFirestoreModule.js +61 -34
  28. package/package.json +3 -3
@@ -8,6 +8,7 @@
8
8
  * @typedef {import('..').FirebaseFirestoreTypes.Query} Query
9
9
  * @typedef {import('..').FirebaseFirestoreTypes.SetOptions} SetOptions
10
10
  * @typedef {import('..').FirebaseFirestoreTypes.Settings} FirestoreSettings
11
+ * @typedef {import('..').FirebaseFirestoreTypes.PersistentCacheIndexManager} PersistentCacheIndexManager
11
12
  * @typedef {import('@firebase/app').FirebaseApp} FirebaseApp
12
13
  */
13
14
 
@@ -15,14 +16,22 @@ import { firebase } from '../index';
15
16
 
16
17
  /**
17
18
  * @param {FirebaseApp?} app
19
+ * @param {String?} databaseId
18
20
  * @returns {Firestore}
19
21
  */
20
- export function getFirestore(app) {
22
+ export function getFirestore(app, databaseId) {
21
23
  if (app) {
22
- return firebase.firestore(app);
24
+ if (databaseId) {
25
+ return firebase.app(app.name).firestore(databaseId);
26
+ } else {
27
+ return firebase.app(app.name).firestore();
28
+ }
29
+ }
30
+ if (databaseId) {
31
+ return firebase.app().firestore(databaseId);
23
32
  }
24
33
 
25
- return firebase.firestore();
34
+ return firebase.app().firestore();
26
35
  }
27
36
 
28
37
  /**
@@ -209,6 +218,49 @@ export function writeBatch(firestore) {
209
218
  return firestore.batch();
210
219
  }
211
220
 
221
+ /**
222
+ * Gets the `PersistentCacheIndexManager` instance used by this Cloud Firestore instance.
223
+ * This is not the same as Cloud Firestore Indexes.
224
+ * Persistent cache indexes are optional indexes that only exist within the SDK to assist in local query execution.
225
+ * Returns `null` if local persistent storage is not in use.
226
+ * @param {Firestore} firestore
227
+ * @returns {PersistentCacheIndexManager | null}
228
+ */
229
+ export function getPersistentCacheIndexManager(firestore) {
230
+ return firestore.persistentCacheIndexManager();
231
+ }
232
+
233
+ /**
234
+ * Enables the SDK to create persistent cache indexes automatically for local query
235
+ * execution when the SDK believes cache indexes can help improves performance.
236
+ * This feature is disabled by default.
237
+ * @param {PersistentCacheIndexManager} indexManager
238
+ * @returns {Promise<void}
239
+ */
240
+ export function enablePersistentCacheIndexAutoCreation(indexManager) {
241
+ return indexManager.enableIndexAutoCreation();
242
+ }
243
+
244
+ /**
245
+ * Stops creating persistent cache indexes automatically for local query execution.
246
+ * The indexes which have been created by calling `enableIndexAutoCreation()` still take effect.
247
+ * @param {PersistentCacheIndexManager} indexManager
248
+ * @returns {Promise<void}
249
+ */
250
+ export function disablePersistentCacheIndexAutoCreation(indexManager) {
251
+ return indexManager.disableIndexAutoCreation();
252
+ }
253
+
254
+ /**
255
+ * Removes all persistent cache indexes. Note this function also deletes indexes
256
+ * generated by `setIndexConfiguration()`, which is deprecated.
257
+ * @param {PersistentCacheIndexManager} indexManager
258
+ * @returns {Promise<void}
259
+ */
260
+ export function deleteAllPersistentCacheIndexes(indexManager) {
261
+ return indexManager.deleteAllIndexes();
262
+ }
263
+
212
264
  export * from './query';
213
265
  export * from './snapshot';
214
266
  export * from './Bytes';
package/lib/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- module.exports = '20.3.0';
2
+ module.exports = '20.4.0';
@@ -68,19 +68,24 @@ function getCachedAppInstance(appName) {
68
68
  return (appInstances[appName] ??= getApp(appName));
69
69
  }
70
70
 
71
+ function createFirestoreKey(appName, databaseId) {
72
+ return `${appName}:${databaseId}`;
73
+ }
74
+
71
75
  // Returns a cached Firestore instance.
72
- function getCachedFirestoreInstance(appName) {
73
- let instance = firestoreInstances[appName];
76
+ function getCachedFirestoreInstance(appName, databaseId) {
77
+ const firestoreKey = createFirestoreKey(appName, databaseId);
78
+ let instance = firestoreInstances[firestoreKey];
74
79
  if (!instance) {
75
- instance = getFirestore(getCachedAppInstance(appName));
76
- if (emulatorForApp[appName]) {
80
+ instance = getFirestore(getCachedAppInstance(appName), databaseId);
81
+ if (emulatorForApp[firestoreKey]) {
77
82
  connectFirestoreEmulator(
78
83
  instance,
79
- emulatorForApp[appName].host,
80
- emulatorForApp[appName].port,
84
+ emulatorForApp[firestoreKey].host,
85
+ emulatorForApp[firestoreKey].port,
81
86
  );
82
87
  }
83
- firestoreInstances[appName] = instance;
88
+ firestoreInstances[firestoreKey] = instance;
84
89
  }
85
90
  return instance;
86
91
  }
@@ -126,27 +131,30 @@ export default {
126
131
  /**
127
132
  * Use the Firestore emulator.
128
133
  * @param {string} appName - The app name.
134
+ * @param {string} databaseId - The database ID.
129
135
  * @param {string} host - The emulator host.
130
136
  * @param {number} port - The emulator port.
131
137
  * @returns {Promise<null>} An empty promise.
132
138
  */
133
- useEmulator(appName, host, port) {
139
+ useEmulator(appName, databaseId, host, port) {
134
140
  return guard(async () => {
135
- const firestore = getCachedFirestoreInstance(appName);
141
+ const firestore = getCachedFirestoreInstance(appName, databaseId);
136
142
  connectFirestoreEmulator(firestore, host, port);
137
- emulatorForApp[appName] = { host, port };
143
+ const firestoreKey = createFirestoreKey(appName, databaseId);
144
+ emulatorForApp[firestoreKey] = { host, port };
138
145
  });
139
146
  },
140
147
 
141
148
  /**
142
149
  * Initializes a Firestore instance with settings.
143
150
  * @param {string} appName - The app name.
151
+ * @param {string} databaseId - The database ID.
144
152
  * @param {object} settings - The Firestore settings.
145
153
  * @returns {Promise<null>} An empty promise.
146
154
  */
147
- settings(appName, settings) {
155
+ settings(appName, databaseId, settings) {
148
156
  return guard(() => {
149
- const instance = initializeFirestore(getCachedAppInstance(appName), settings);
157
+ const instance = initializeFirestore(getCachedAppInstance(appName), settings, databaseId);
150
158
  firestoreInstances[appName] = instance;
151
159
  });
152
160
  },
@@ -154,11 +162,12 @@ export default {
154
162
  /**
155
163
  * Terminates a Firestore instance.
156
164
  * @param {string} appName - The app name.
165
+ * @param {string} databaseId - The database ID.
157
166
  * @returns {Promise<null>} An empty promise.
158
167
  */
159
- terminate(appName) {
168
+ terminate(appName, databaseId) {
160
169
  return guard(async () => {
161
- const firestore = getCachedFirestoreInstance(appName);
170
+ const firestore = getCachedFirestoreInstance(appName, databaseId);
162
171
  await terminate(firestore);
163
172
  return null;
164
173
  });
@@ -184,6 +193,7 @@ export default {
184
193
  /**
185
194
  * Get a collection count from Firestore.
186
195
  * @param {string} appName - The app name.
196
+ * @param {string} databaseId - The database ID.
187
197
  * @param {string} path - The collection path.
188
198
  * @param {string} type - The collection type (e.g. collectionGroup).
189
199
  * @param {object[]} filters - The collection filters.
@@ -191,9 +201,9 @@ export default {
191
201
  * @param {object} options - The collection options.
192
202
  * @returns {Promise<object>} The collection count object.
193
203
  */
194
- collectionCount(appName, path, type, filters, orders, options) {
204
+ collectionCount(appName, databaseId, path, type, filters, orders, options) {
195
205
  return guard(async () => {
196
- const firestore = getCachedFirestoreInstance(appName);
206
+ const firestore = getCachedFirestoreInstance(appName, databaseId);
197
207
  const queryRef =
198
208
  type === 'collectionGroup' ? collectionGroup(firestore, path) : collection(firestore, path);
199
209
  const query = buildQuery(queryRef, filters, orders, options);
@@ -208,6 +218,7 @@ export default {
208
218
  /**
209
219
  * Get a collection from Firestore.
210
220
  * @param {string} appName - The app name.
221
+ * @param {string} databaseId - The database ID.
211
222
  * @param {string} path - The collection path.
212
223
  * @param {string} type - The collection type (e.g. collectionGroup).
213
224
  * @param {object[]} filters - The collection filters.
@@ -216,7 +227,7 @@ export default {
216
227
  * @param {object} getOptions - The get options.
217
228
  * @returns {Promise<object>} The collection object.
218
229
  */
219
- collectionGet(appName, path, type, filters, orders, options, getOptions) {
230
+ collectionGet(appName, databaseId, path, type, filters, orders, options, getOptions) {
220
231
  if (getOptions && getOptions.source === 'cache') {
221
232
  return rejectWithCodeAndMessage(
222
233
  'unsupported',
@@ -225,7 +236,7 @@ export default {
225
236
  }
226
237
 
227
238
  return guard(async () => {
228
- const firestore = getCachedFirestoreInstance(appName);
239
+ const firestore = getCachedFirestoreInstance(appName, databaseId);
229
240
  const queryRef =
230
241
  type === 'collectionGroup' ? collectionGroup(firestore, path) : collection(firestore, path);
231
242
  const query = buildQuery(queryRef, filters, orders, options);
@@ -243,14 +254,19 @@ export default {
243
254
  return rejectWithCodeAndMessage('unsupported', 'Not supported in the lite SDK.');
244
255
  },
245
256
 
257
+ persistenceCacheIndexManager() {
258
+ return rejectWithCodeAndMessage('unsupported', 'Not supported in the lite SDK.');
259
+ },
260
+
246
261
  /**
247
262
  * Get a document from Firestore.
248
263
  * @param {string} appName - The app name.
264
+ * @param {string} databaseId - The database ID.
249
265
  * @param {string} path - The document path.
250
266
  * @param {object} getOptions - The get options.
251
267
  * @returns {Promise<object>} The document object.
252
268
  */
253
- documentGet(appName, path, getOptions) {
269
+ documentGet(appName, databaseId, path, getOptions) {
254
270
  return guard(async () => {
255
271
  if (getOptions && getOptions.source === 'cache') {
256
272
  return rejectWithCodeAndMessage(
@@ -259,7 +275,7 @@ export default {
259
275
  );
260
276
  }
261
277
 
262
- const firestore = getCachedFirestoreInstance(appName);
278
+ const firestore = getCachedFirestoreInstance(appName, databaseId);
263
279
  const ref = doc(firestore, path);
264
280
  const snapshot = await getDoc(ref);
265
281
  return documentSnapshotToObject(snapshot);
@@ -269,12 +285,13 @@ export default {
269
285
  /**
270
286
  * Delete a document from Firestore.
271
287
  * @param {string} appName - The app name.
288
+ * @param {string} databaseId - The database ID.
272
289
  * @param {string} path - The document path.
273
290
  * @returns {Promise<null>} An empty promise.
274
291
  */
275
- documentDelete(appName, path) {
292
+ documentDelete(appName, databaseId, path) {
276
293
  return guard(async () => {
277
- const firestore = getCachedFirestoreInstance(appName);
294
+ const firestore = getCachedFirestoreInstance(appName, databaseId);
278
295
  const ref = doc(firestore, path);
279
296
  await deleteDoc(ref);
280
297
  return null;
@@ -284,14 +301,15 @@ export default {
284
301
  /**
285
302
  * Set a document in Firestore.
286
303
  * @param {string} appName - The app name.
304
+ * @param {string} databaseId - The database ID.
287
305
  * @param {string} path - The document path.
288
306
  * @param {object} data - The document data.
289
307
  * @param {object} options - The set options.
290
308
  * @returns {Promise<null>} An empty promise.
291
309
  */
292
- documentSet(appName, path, data, options) {
310
+ documentSet(appName, databaseId, path, data, options) {
293
311
  return guard(async () => {
294
- const firestore = getCachedFirestoreInstance(appName);
312
+ const firestore = getCachedFirestoreInstance(appName, databaseId);
295
313
  const ref = doc(firestore, path);
296
314
  const setOptions = {};
297
315
  if ('merge' in options) {
@@ -306,13 +324,14 @@ export default {
306
324
  /**
307
325
  * Update a document in Firestore.
308
326
  * @param {string} appName - The app name.
327
+ * @param {string} databaseId - The database ID.
309
328
  * @param {string} path - The document path.
310
329
  * @param {object} data - The document data.
311
330
  * @returns {Promise<null>} An empty promise.
312
331
  */
313
- documentUpdate(appName, path, data) {
332
+ documentUpdate(appName, databaseId, path, data) {
314
333
  return guard(async () => {
315
- const firestore = getCachedFirestoreInstance(appName);
334
+ const firestore = getCachedFirestoreInstance(appName, databaseId);
316
335
  const ref = doc(firestore, path);
317
336
  await updateDoc(ref, readableToObject(firestore, data));
318
337
  });
@@ -321,11 +340,12 @@ export default {
321
340
  /**
322
341
  * Batch write documents in Firestore.
323
342
  * @param {string} appName - The app name.
343
+ * @param {string} databaseId - The database ID.
324
344
  * @param {object[]} writes - The document writes in write batches format.
325
345
  */
326
- documentBatch(appName, writes) {
346
+ documentBatch(appName, databaseId, writes) {
327
347
  return guard(async () => {
328
- const firestore = getCachedFirestoreInstance(appName);
348
+ const firestore = getCachedFirestoreInstance(appName, databaseId);
329
349
  const batch = writeBatch(firestore);
330
350
  const writesArray = parseDocumentBatches(firestore, writes);
331
351
 
@@ -360,11 +380,12 @@ export default {
360
380
  /**
361
381
  * Get a document from a Firestore transaction.
362
382
  * @param {string} appName - The app name.
383
+ * @param {string} databaseId - The database ID.
363
384
  * @param {string} transactionId - The transaction id.
364
385
  * @param {string} path - The document path.
365
386
  * @returns {Promise<object>} The document object.
366
387
  */
367
- transactionGetDocument(appName, transactionId, path) {
388
+ transactionGetDocument(appName, databaseId, transactionId, path) {
368
389
  if (!transactionHandler[transactionId]) {
369
390
  return rejectWithCodeAndMessage(
370
391
  'internal-error',
@@ -373,7 +394,7 @@ export default {
373
394
  }
374
395
 
375
396
  return guard(async () => {
376
- const firestore = getCachedFirestoreInstance(appName);
397
+ const firestore = getCachedFirestoreInstance(appName, databaseId);
377
398
  const docRef = doc(firestore, path);
378
399
  const tsx = transactionHandler[transactionId];
379
400
  const snapshot = await tsx.get(docRef);
@@ -384,9 +405,10 @@ export default {
384
405
  /**
385
406
  * Dispose a transaction instance.
386
407
  * @param {string} appName - The app name.
408
+ * @param {string} databaseId - The database ID.
387
409
  * @param {string} transactionId - The transaction id.
388
410
  */
389
- transactionDispose(appName, transactionId) {
411
+ transactionDispose(appName, databaseId, transactionId) {
390
412
  // There's no abort method in the JS SDK, so we just remove the transaction handler.
391
413
  delete transactionHandler[transactionId];
392
414
  },
@@ -394,10 +416,11 @@ export default {
394
416
  /**
395
417
  * Applies a buffer of commands to a Firestore transaction.
396
418
  * @param {string} appName - The app name.
419
+ * @param {string} databaseId - The database ID.
397
420
  * @param {string} transactionId - The transaction id.
398
421
  * @param {object[]} commandBuffer - The readable array of buffer commands.
399
422
  */
400
- transactionApplyBuffer(appName, transactionId, commandBuffer) {
423
+ transactionApplyBuffer(appName, databaseId, transactionId, commandBuffer) {
401
424
  if (transactionHandler[transactionId]) {
402
425
  transactionBuffer[transactionId] = commandBuffer;
403
426
  }
@@ -406,12 +429,13 @@ export default {
406
429
  /**
407
430
  * Begins a Firestore transaction.
408
431
  * @param {string} appName - The app name.
432
+ * @param {string} databaseId - The database ID.
409
433
  * @param {string} transactionId - The transaction id.
410
434
  * @returns {Promise<null>} An empty promise.
411
435
  */
412
- transactionBegin(appName, transactionId) {
436
+ transactionBegin(appName, databaseId, transactionId) {
413
437
  return guard(async () => {
414
- const firestore = getCachedFirestoreInstance(appName);
438
+ const firestore = getCachedFirestoreInstance(appName, databaseId);
415
439
 
416
440
  try {
417
441
  await runTransaction(firestore, async tsx => {
@@ -421,6 +445,7 @@ export default {
421
445
  eventName: 'firestore_transaction_event',
422
446
  body: { type: 'update' },
423
447
  appName,
448
+ databaseId,
424
449
  listenerId: transactionId,
425
450
  });
426
451
 
@@ -468,6 +493,7 @@ export default {
468
493
  eventName: 'firestore_transaction_event',
469
494
  body: { type: 'complete' },
470
495
  appName,
496
+ databaseId,
471
497
  listenerId: transactionId,
472
498
  });
473
499
  } catch (e) {
@@ -475,6 +501,7 @@ export default {
475
501
  eventName: 'firestore_transaction_event',
476
502
  body: { type: 'error', error: getWebError(e) },
477
503
  appName,
504
+ databaseId,
478
505
  listenerId: transactionId,
479
506
  });
480
507
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-native-firebase/firestore",
3
- "version": "20.3.0",
3
+ "version": "20.4.0",
4
4
  "author": "Invertase <oss@invertase.io> (http://invertase.io)",
5
5
  "description": "React Native Firebase - Cloud Firestore is a NoSQL cloud database to store and sync data between your React Native application and Firebase's database. The API matches the Firebase Web SDK whilst taking advantage of the native SDKs performance and offline capabilities.",
6
6
  "main": "lib/index.js",
@@ -27,10 +27,10 @@
27
27
  "firestore"
28
28
  ],
29
29
  "peerDependencies": {
30
- "@react-native-firebase/app": "20.3.0"
30
+ "@react-native-firebase/app": "20.4.0"
31
31
  },
32
32
  "publishConfig": {
33
33
  "access": "public"
34
34
  },
35
- "gitHead": "a916b37b022cf40588fa0fd915b7ab901e2458d0"
35
+ "gitHead": "3ac3e9623674a8db52c111b4aa0a85a883260116"
36
36
  }