@react-native-firebase/database 20.1.0 → 20.2.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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,20 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [20.2.1](https://github.com/invertase/react-native-firebase/compare/v20.2.0...v20.2.1) (2024-07-17)
7
+
8
+ **Note:** Version bump only for package @react-native-firebase/database
9
+
10
+ ## [20.2.0](https://github.com/invertase/react-native-firebase/compare/v20.1.0...v20.2.0) (2024-07-15)
11
+
12
+ ### Features
13
+
14
+ - **other:** Add Database support ([#7887](https://github.com/invertase/react-native-firebase/issues/7887)) ([fbb773a](https://github.com/invertase/react-native-firebase/commit/fbb773a87c167bdc92265fe261aeb777d4660cd7))
15
+
16
+ ### Bug Fixes
17
+
18
+ - **database:** set priority on child snapshot if available ([#7897](https://github.com/invertase/react-native-firebase/issues/7897)) ([9028ae4](https://github.com/invertase/react-native-firebase/commit/9028ae4785eb17239ae2ab49d343a39c01a349e7))
19
+
6
20
  ## [20.1.0](https://github.com/invertase/react-native-firebase/compare/v20.0.0...v20.1.0) (2024-06-04)
7
21
 
8
22
  **Note:** Version bump only for package @react-native-firebase/database
@@ -24,10 +24,13 @@ import android.util.Log;
24
24
  import com.facebook.react.bridge.*;
25
25
  import com.google.firebase.database.DataSnapshot;
26
26
  import com.google.firebase.database.MutableData;
27
+ import java.util.HashMap;
27
28
  import javax.annotation.Nullable;
28
29
 
29
30
  public class ReactNativeFirebaseDatabaseCommon {
30
31
  private static final String TAG = "DatabaseCommon";
32
+ private static final String childPrioritiesKey = "childPriorities";
33
+ private static final String childKeysKey = "childKeys";
31
34
 
32
35
  /**
33
36
  * @param promise
@@ -61,12 +64,13 @@ public class ReactNativeFirebaseDatabaseCommon {
61
64
  */
62
65
  public static WritableMap snapshotToMap(DataSnapshot dataSnapshot) {
63
66
  WritableMap snapshot = Arguments.createMap();
64
-
67
+ HashMap<String, Object> childProperties = getChildProperties(dataSnapshot);
65
68
  snapshot.putString("key", dataSnapshot.getKey());
66
69
  snapshot.putBoolean("exists", dataSnapshot.exists());
67
70
  snapshot.putBoolean("hasChildren", dataSnapshot.hasChildren());
68
71
  snapshot.putDouble("childrenCount", dataSnapshot.getChildrenCount());
69
- snapshot.putArray("childKeys", getChildKeys(dataSnapshot));
72
+ snapshot.putArray(childKeysKey, (ReadableArray) childProperties.get(childKeysKey));
73
+ snapshot.putMap(childPrioritiesKey, (WritableMap) childProperties.get(childPrioritiesKey));
70
74
  mapPutValue("priority", dataSnapshot.getPriority(), snapshot);
71
75
 
72
76
  if (!dataSnapshot.hasChildren()) {
@@ -369,15 +373,29 @@ public class ReactNativeFirebaseDatabaseCommon {
369
373
  * @param snapshot
370
374
  * @return
371
375
  */
372
- public static WritableArray getChildKeys(DataSnapshot snapshot) {
376
+ public static HashMap<String, Object> getChildProperties(DataSnapshot snapshot) {
373
377
  WritableArray childKeys = Arguments.createArray();
374
-
378
+ WritableMap childPriorities = Arguments.createMap();
379
+ HashMap<String, Object> childProperties = new HashMap<>();
375
380
  if (snapshot.hasChildren()) {
376
381
  for (DataSnapshot child : snapshot.getChildren()) {
377
382
  childKeys.pushString(child.getKey());
383
+
384
+ Object priority = child.getPriority();
385
+ // Priority can be String, Double or null
386
+ if (priority instanceof String) {
387
+ childPriorities.putString(child.getKey(), (String) priority);
388
+ } else if (priority instanceof Double) {
389
+ childPriorities.putDouble(child.getKey(), (Double) priority);
390
+ } else if (priority == null) {
391
+ childPriorities.putNull(child.getKey());
392
+ }
378
393
  }
379
394
  }
380
395
 
381
- return childKeys;
396
+ childProperties.put(childKeysKey, childKeys);
397
+ childProperties.put(childPrioritiesKey, childPriorities);
398
+
399
+ return childProperties;
382
400
  }
383
401
  }
@@ -26,6 +26,9 @@ NSString *const DATABASE_PERSISTENCE_ENABLED = @"firebase_database_persistence_e
26
26
  NSString *const DATABASE_LOGGING_ENABLED = @"firebase_database_logging_enabled";
27
27
  NSString *const DATABASE_PERSISTENCE_CACHE_SIZE = @"firebase_database_persistence_cache_size_bytes";
28
28
 
29
+ NSString *const childPrioritiesKey = @"childPriorities";
30
+ NSString *const childKeysKey = @"childKeys";
31
+
29
32
  @implementation RNFBDatabaseCommon
30
33
 
31
34
  + (void)load {
@@ -250,28 +253,32 @@ NSString *const DATABASE_PERSISTENCE_CACHE_SIZE = @"firebase_database_persistenc
250
253
  } else {
251
254
  [snapshot setValue:[NSNull null] forKey:@"key"];
252
255
  }
256
+ NSMutableDictionary *childProperties = [self getSnapshotChildProperties:dataSnapshot];
253
257
  [snapshot setValue:@(dataSnapshot.exists) forKey:@"exists"];
254
258
  [snapshot setValue:@(dataSnapshot.hasChildren) forKey:@"hasChildren"];
255
259
  [snapshot setValue:@(dataSnapshot.childrenCount) forKey:@"childrenCount"];
256
- [snapshot setValue:[self getSnapshotChildKeys:dataSnapshot] forKey:@"childKeys"];
260
+ [snapshot setValue:childProperties[childKeysKey] forKey:childKeysKey];
261
+ [snapshot setValue:childProperties[childPrioritiesKey] forKey:childPrioritiesKey];
257
262
  [snapshot setValue:dataSnapshot.priority forKey:@"priority"];
258
263
  [snapshot setValue:dataSnapshot.value forKey:@"value"];
259
264
 
260
265
  return snapshot;
261
266
  }
262
267
 
263
- + (NSMutableArray *)getSnapshotChildKeys:(FIRDataSnapshot *)dataSnapshot {
268
+ + (NSMutableDictionary *)getSnapshotChildProperties:(FIRDataSnapshot *)dataSnapshot {
264
269
  NSMutableArray *childKeys = [NSMutableArray array];
270
+ NSMutableDictionary *childPriorities = [[NSMutableDictionary alloc] init];
265
271
  if (dataSnapshot.childrenCount > 0) {
266
272
  NSEnumerator *children = [dataSnapshot children];
267
273
  FIRDataSnapshot *child;
268
274
  child = [children nextObject];
269
275
  while (child) {
270
276
  [childKeys addObject:child.key];
277
+ [childPriorities setValue:child.priority forKey:child.key];
271
278
  child = [children nextObject];
272
279
  }
273
280
  }
274
- return childKeys;
281
+ return @{childKeysKey : childKeys, childPrioritiesKey : childPriorities};
275
282
  }
276
283
 
277
284
  @end
@@ -15,7 +15,13 @@
15
15
  *
16
16
  */
17
17
 
18
- import { isArray, isFunction, isObject, isString } from '@react-native-firebase/app/lib/common';
18
+ import {
19
+ isArray,
20
+ isFunction,
21
+ isObject,
22
+ isString,
23
+ isNumber,
24
+ } from '@react-native-firebase/app/lib/common';
19
25
  import { deepGet } from '@react-native-firebase/app/lib/common/deeps';
20
26
 
21
27
  export default class DatabaseDataSnapshot {
@@ -61,11 +67,19 @@ export default class DatabaseDataSnapshot {
61
67
 
62
68
  const childRef = this._ref.child(path);
63
69
 
70
+ let childPriority = null;
71
+ if (this._snapshot.childPriorities) {
72
+ const childPriorityValue = this._snapshot.childPriorities[childRef.key];
73
+ if (isString(childPriorityValue) || isNumber(childPriorityValue)) {
74
+ childPriority = childPriorityValue;
75
+ }
76
+ }
64
77
  return new DatabaseDataSnapshot(childRef, {
65
78
  value,
66
79
  key: childRef.key,
67
80
  exists: value !== null,
68
81
  childKeys: isObject(value) ? Object.keys(value) : [],
82
+ priority: childPriority,
69
83
  });
70
84
  }
71
85
 
@@ -16,9 +16,9 @@
16
16
  */
17
17
 
18
18
  import { isString } from '@react-native-firebase/app/lib/common';
19
+ import { getReactNativeModule } from '@react-native-firebase/app/lib/internal/nativeModule';
19
20
  import NativeError from '@react-native-firebase/app/lib/internal/NativeFirebaseError';
20
21
  import SharedEventEmitter from '@react-native-firebase/app/lib/internal/SharedEventEmitter';
21
- import { NativeModules } from 'react-native';
22
22
  import DatabaseDataSnapshot from './DatabaseDataSnapshot';
23
23
 
24
24
  class DatabaseSyncTree {
@@ -39,7 +39,7 @@ class DatabaseSyncTree {
39
39
  }
40
40
 
41
41
  get native() {
42
- return NativeModules.RNFBDatabaseQueryModule;
42
+ return getReactNativeModule('RNFBDatabaseQueryModule');
43
43
  }
44
44
 
45
45
  // from upstream EventEmitter: initialize registrations for an emitter key
@@ -16,6 +16,7 @@
16
16
  */
17
17
 
18
18
  import NativeError from '@react-native-firebase/app/lib/internal/NativeFirebaseError';
19
+ import { isOther } from '@react-native-firebase/app/lib/common';
19
20
 
20
21
  let transactionId = 0;
21
22
 
@@ -59,7 +60,11 @@ export default class DatabaseTransaction {
59
60
  started: true,
60
61
  };
61
62
 
62
- this._database.native.transactionStart(reference.path, id, applyLocally);
63
+ if (isOther) {
64
+ this._database.native.transactionStart(reference.path, id, applyLocally, transactionUpdater);
65
+ } else {
66
+ this._database.native.transactionStart(reference.path, id, applyLocally);
67
+ }
63
68
  }
64
69
 
65
70
  /**
package/lib/index.js CHANGED
@@ -21,10 +21,12 @@ import {
21
21
  FirebaseModule,
22
22
  getFirebaseRoot,
23
23
  } from '@react-native-firebase/app/lib/internal';
24
+ import { setReactNativeModule } from '@react-native-firebase/app/lib/internal/nativeModule';
24
25
  import DatabaseReference from './DatabaseReference';
25
26
  import DatabaseStatics from './DatabaseStatics';
26
27
  import DatabaseTransaction from './DatabaseTransaction';
27
28
  import version from './version';
29
+ import fallBackModule from './web/RNFBDatabaseModule';
28
30
 
29
31
  const namespace = 'database';
30
32
 
@@ -222,3 +224,7 @@ export * from './modular';
222
224
  // database().X(...);
223
225
  // firebase.database().X(...);
224
226
  export const firebase = getFirebaseRoot();
227
+
228
+ for (let i = 0; i < nativeModuleName.length; i++) {
229
+ setReactNativeModule(nativeModuleName[i], fallBackModule);
230
+ }
package/lib/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- module.exports = '20.1.0';
2
+ module.exports = '20.2.1';
@@ -0,0 +1,2 @@
1
+ // No-op for android.
2
+ export default {};
@@ -0,0 +1,2 @@
1
+ // No-op for ios.
2
+ export default {};
@@ -0,0 +1,545 @@
1
+ import {
2
+ getApp,
3
+ getDatabase,
4
+ connectDatabaseEmulator,
5
+ enableLogging,
6
+ goOnline,
7
+ goOffline,
8
+ ref,
9
+ set,
10
+ update,
11
+ setWithPriority,
12
+ remove,
13
+ setPriority,
14
+ onDisconnect,
15
+ onValue,
16
+ onChildAdded,
17
+ onChildChanged,
18
+ onChildMoved,
19
+ onChildRemoved,
20
+ runTransaction,
21
+ } from '@react-native-firebase/app/lib/internal/web/firebaseDatabase';
22
+ import { guard, getWebError, emitEvent } from '@react-native-firebase/app/lib/internal/web/utils';
23
+ import { getQueryInstance } from './query';
24
+
25
+ // Converts a DataSnapshot to an object.
26
+ function snapshotToObject(snapshot) {
27
+ const childKeys = [];
28
+
29
+ if (snapshot.hasChildren()) {
30
+ snapshot.forEach(childSnapshot => {
31
+ childKeys.push(childSnapshot.key);
32
+ });
33
+ }
34
+
35
+ return {
36
+ key: snapshot.key,
37
+ exists: snapshot.exists(),
38
+ hasChildren: snapshot.hasChildren(),
39
+ childrenCount: snapshot.size,
40
+ childKeys,
41
+ priority: snapshot.priority,
42
+ value: snapshot.val(),
43
+ };
44
+ }
45
+
46
+ function getDatabaseWebError(error) {
47
+ // Possible to override messages/codes here if necessary.
48
+ return getWebError(error);
49
+ }
50
+
51
+ // Converts a DataSnapshot and previous child name to an object.
52
+ function snapshotWithPreviousChildToObject(snapshot, previousChildName) {
53
+ return {
54
+ snapshot: snapshotToObject(snapshot),
55
+ previousChildName,
56
+ };
57
+ }
58
+
59
+ const appInstances = {};
60
+ const databaseInstances = {};
61
+ const onDisconnectRef = {};
62
+ const listeners = {};
63
+ const emulatorForApp = {};
64
+
65
+ function getCachedAppInstance(appName) {
66
+ return (appInstances[appName] ??= getApp(appName));
67
+ }
68
+
69
+ // Returns a cached Database instance.
70
+ function getCachedDatabaseInstance(appName, dbURL) {
71
+ let instance = databaseInstances[`${appName}|${dbURL}`];
72
+ if (!instance) {
73
+ instance = getDatabase(getCachedAppInstance(appName), dbURL);
74
+ // Relying on internals here so need to be careful between SDK versions.
75
+ if (emulatorForApp[appName] && !instance._instanceStarted) {
76
+ const { host, port } = emulatorForApp[appName];
77
+ connectDatabaseEmulator(instance, host, port);
78
+ emulatorForApp[appName].connected = true;
79
+ }
80
+ }
81
+ return instance;
82
+ }
83
+
84
+ // Returns a cached onDisconnect instance.
85
+ function getCachedOnDisconnectInstance(ref) {
86
+ return (onDisconnectRef[ref.key] ??= onDisconnect(ref));
87
+ }
88
+
89
+ export default {
90
+ /**
91
+ * Reconnects to the server.
92
+ * @param {string} appName - The app name.
93
+ * @param {string} dbURL - The database URL.
94
+ * @returns {Promise<void>}
95
+ */
96
+ goOnline(appName, dbURL) {
97
+ return guard(async () => {
98
+ const db = getCachedDatabaseInstance(appName, dbURL);
99
+ goOnline(db);
100
+ });
101
+ },
102
+
103
+ /**
104
+ * Disconnects from the server.
105
+ * @param {string} appName - The app name.
106
+ * @param {string} dbURL - The database URL.
107
+ * @returns {Promise<void>}
108
+ */
109
+ goOffline(appName, dbURL) {
110
+ return guard(async () => {
111
+ const db = getCachedDatabaseInstance(appName, dbURL);
112
+ goOffline(db);
113
+ });
114
+ },
115
+
116
+ setPersistenceEnabled() {
117
+ if (__DEV__) {
118
+ // eslint-disable-next-line no-console
119
+ console.warn(
120
+ 'The Firebase Database `setPersistenceEnabled` method is not available in the this environment.',
121
+ );
122
+ }
123
+ return Promise.resolve();
124
+ },
125
+
126
+ /**
127
+ * Sets the logging enabled state.
128
+ * @param {string} appName - The app name, not used.
129
+ * @param {string} dbURL - The database URL, not used.
130
+ * @param {boolean} enabled - The logging enabled state.
131
+ */
132
+ setLoggingEnabled(app, dbURL, enabled) {
133
+ return guard(async () => {
134
+ enableLogging(enabled);
135
+ });
136
+ },
137
+
138
+ setPersistenceCacheSizeBytes() {
139
+ // no-op on other platforms
140
+ return Promise.resolve();
141
+ },
142
+
143
+ /**
144
+ * Connects to the Firebase database emulator.
145
+ * @param {string} appName - The app name.
146
+ * @param {string} dbURL - The database URL.
147
+ * @param {string} host - The emulator host.
148
+ * @param {number} port - The emulator
149
+ * @returns {Promise<void>}
150
+ */
151
+ useEmulator(appName, dbURL, host, port) {
152
+ return guard(async () => {
153
+ const db = getCachedDatabaseInstance(appName, dbURL);
154
+ connectDatabaseEmulator(db, host, port);
155
+ emulatorForApp[appName] = { host, port };
156
+ });
157
+ },
158
+
159
+ /**
160
+ * Reference
161
+ */
162
+
163
+ /**
164
+ * Sets a value at the specified path.
165
+ * @param {string} appName - The app name.
166
+ * @param {string} dbURL - The database URL.
167
+ * @param {string} path - The path.
168
+ * @param {object} props - The properties
169
+ * @returns {Promise<void>}
170
+ */
171
+ set(appName, dbURL, path, props) {
172
+ return guard(async () => {
173
+ const db = getCachedDatabaseInstance(appName, dbURL);
174
+ const dbRef = ref(db, path);
175
+ const value = props.value;
176
+ await set(dbRef, value);
177
+ });
178
+ },
179
+
180
+ /**
181
+ * Updates the specified path with the provided values.
182
+ * @param {string} appName - The app name.
183
+ * @param {string} dbURL - The database URL.
184
+ * @param {string} path - The path.
185
+ * @param {object} props - The properties
186
+ * @returns {Promise<void>}
187
+ */
188
+ update(appName, dbURL, path, props) {
189
+ return guard(async () => {
190
+ const db = getCachedDatabaseInstance(appName, dbURL);
191
+ const dbRef = ref(db, path);
192
+ const values = props.values;
193
+ await update(dbRef, values);
194
+ });
195
+ },
196
+
197
+ /**
198
+ * Sets a value at the specified path with a priority.
199
+ * @param {string} appName - The app name.
200
+ * @param {string} dbURL - The database URL.
201
+ * @param {string} path - The path.
202
+ * @param {object} props - The properties, including value and priority.
203
+ * @returns {Promise<void>}
204
+ */
205
+ setWithPriority(appName, dbURL, path, props) {
206
+ return guard(async () => {
207
+ const db = getCachedDatabaseInstance(appName, dbURL);
208
+ const dbRef = ref(db, path);
209
+ const value = props.value;
210
+ const priority = props.priority;
211
+ await setWithPriority(dbRef, value, priority);
212
+ });
213
+ },
214
+
215
+ /**
216
+ * Removes the nodd at the specified path.
217
+ * @param {string} appName - The app name.
218
+ * @param {string} dbURL - The database URL.
219
+ * @param {string} path - The path.
220
+ * @returns {Promise<void>}
221
+ */
222
+ remove(appName, dbURL, path) {
223
+ return guard(async () => {
224
+ const db = getCachedDatabaseInstance(appName, dbURL);
225
+ const dbRef = ref(db, path);
226
+ await remove(dbRef);
227
+ });
228
+ },
229
+
230
+ /**
231
+ * Sets the priority of the node at the specified path.
232
+ * @param {string} appName - The app name.
233
+ * @param {string} dbURL - The database URL.
234
+ * @param {string} path - The path.
235
+ * @param {object} props - The properties, including priority.
236
+ * @returns {Promise<void>}
237
+ */
238
+ setPriority(appName, dbURL, path, props) {
239
+ return guard(async () => {
240
+ const db = getCachedDatabaseInstance(appName, dbURL);
241
+ const dbRef = ref(db, path);
242
+ const priority = props.priority;
243
+ await setPriority(dbRef, priority);
244
+ });
245
+ },
246
+
247
+ /**
248
+ * Query
249
+ */
250
+
251
+ /**
252
+ * Listens for data changes at the specified path once.
253
+ * @param {string} appName - The app name.
254
+ * @param {string} dbURL - The database URL.
255
+ * @param {string} path - The path.
256
+ * @param {object} modifiers - The modifiers.
257
+ * @param {string} eventType - The event type.
258
+ * @returns {Promise<object>}
259
+ */
260
+ once(appName, dbURL, path, modifiers, eventType) {
261
+ return guard(async () => {
262
+ const db = getCachedDatabaseInstance(appName, dbURL);
263
+ const dbRef = ref(db, path);
264
+ const queryRef = getQueryInstance(dbRef, modifiers);
265
+
266
+ if (eventType === 'value') {
267
+ const snapshot = await new Promise((resolve, reject) => {
268
+ onValue(queryRef, resolve, reject, { onlyOnce: true });
269
+ });
270
+
271
+ return snapshotToObject(snapshot);
272
+ } else {
273
+ let fn = null;
274
+
275
+ if (eventType === 'child_added') {
276
+ fn = onChildAdded;
277
+ } else if (eventType === 'child_changed') {
278
+ fn = onChildChanged;
279
+ } else if (eventType === 'child_removed') {
280
+ fn = onChildRemoved;
281
+ } else if (eventType === 'child_moved') {
282
+ fn = onChildMoved;
283
+ }
284
+
285
+ if (fn) {
286
+ const { snapshot, previousChildName } = await new Promise((resolve, reject) => {
287
+ fn(
288
+ queryRef,
289
+ (snapshot, previousChildName) => {
290
+ resolve({ snapshot, previousChildName });
291
+ },
292
+ reject,
293
+ { onlyOnce: true },
294
+ );
295
+ });
296
+
297
+ return snapshotWithPreviousChildToObject(snapshot, previousChildName);
298
+ }
299
+ }
300
+
301
+ const snapshot = await get(dbRef, modifiers);
302
+ return snapshot;
303
+ });
304
+ },
305
+
306
+ on(appName, dbURL, props) {
307
+ return guard(async () => {
308
+ const db = getCachedDatabaseInstance(appName, dbURL);
309
+ const { key, modifiers, path, eventType, registration } = props;
310
+ const { eventRegistrationKey } = registration;
311
+ const dbRef = ref(db, path);
312
+
313
+ const queryRef = getQueryInstance(dbRef, modifiers);
314
+
315
+ function sendEvent(data) {
316
+ const event = {
317
+ eventName: 'database_sync_event',
318
+ body: {
319
+ data,
320
+ key,
321
+ registration,
322
+ eventType,
323
+ },
324
+ };
325
+
326
+ emitEvent('database_sync_event', event);
327
+ }
328
+
329
+ function sendError(error) {
330
+ const event = {
331
+ eventName: 'database_sync_event',
332
+ body: {
333
+ key,
334
+ registration,
335
+ error: getDatabaseWebError(error),
336
+ },
337
+ };
338
+
339
+ emitEvent('database_sync_event', event);
340
+ }
341
+
342
+ let listener = null;
343
+
344
+ // Ignore if the listener already exists.
345
+ if (listeners[eventRegistrationKey]) {
346
+ return;
347
+ }
348
+
349
+ if (eventType === 'value') {
350
+ listener = onValue(queryRef, snapshot => sendEvent(snapshotToObject(snapshot)), sendError);
351
+ } else {
352
+ let fn = null;
353
+
354
+ if (eventType === 'child_added') {
355
+ fn = onChildAdded;
356
+ } else if (eventType === 'child_changed') {
357
+ fn = onChildChanged;
358
+ } else if (eventType === 'child_removed') {
359
+ fn = onChildRemoved;
360
+ } else if (eventType === 'child_moved') {
361
+ fn = onChildMoved;
362
+ }
363
+
364
+ if (fn) {
365
+ listener = fn(
366
+ queryRef,
367
+ (snapshot, previousChildName) => {
368
+ sendEvent(snapshotWithPreviousChildToObject(snapshot, previousChildName));
369
+ },
370
+ sendError,
371
+ );
372
+ }
373
+ }
374
+
375
+ listeners[eventRegistrationKey] = listener;
376
+ });
377
+ },
378
+
379
+ off(queryKey, eventRegistrationKey) {
380
+ const listener = listeners[eventRegistrationKey];
381
+ if (listener) {
382
+ listener();
383
+ delete listeners[eventRegistrationKey];
384
+ }
385
+ },
386
+
387
+ keepSynced() {
388
+ return rejectPromiseWithCodeAndMessage(
389
+ 'unsupported',
390
+ 'This operation is not supported on this environment.',
391
+ );
392
+ },
393
+
394
+ /**
395
+ * OnDisconnect
396
+ */
397
+
398
+ /**
399
+ * Cancels the onDisconnect instance at the specified path.
400
+ * @param {string} appName - The app name.
401
+ * @param {string} dbURL - The database URL.
402
+ * @param {string} path - The path.
403
+ * @returns {Promise<void>}
404
+ */
405
+ onDisconnectCancel(appName, dbURL, path) {
406
+ return guard(async () => {
407
+ const db = getCachedDatabaseInstance(appName, dbURL);
408
+ const dbRef = ref(db, path);
409
+ const instance = getCachedOnDisconnectInstance(dbRef);
410
+ await instance.cancel();
411
+
412
+ // Delete the onDisconnect instance from the cache.
413
+ delete onDisconnectRef[dbRef.key];
414
+ });
415
+ },
416
+
417
+ /**
418
+ * Sets a value to be written to the database on disconnect.
419
+ * @param {string} appName - The app name.
420
+ * @param {string} dbURL - The database URL.
421
+ * @param {string} path - The path.
422
+ * @returns {Promise<void>}
423
+ */
424
+ onDisconnectRemove(appName, dbURL, path) {
425
+ return guard(async () => {
426
+ const db = getCachedDatabaseInstance(appName, dbURL);
427
+ const dbRef = ref(db, path);
428
+ const instance = getCachedOnDisconnectInstance(dbRef);
429
+ await instance.remove();
430
+ });
431
+ },
432
+
433
+ /**
434
+ * Sets a value to be written to the database on disconnect.
435
+ * @param {string} appName - The app name.
436
+ * @param {string} dbURL - The database URL.
437
+ * @param {string} path - The path.
438
+ * @param {object} props - The properties, including value.
439
+ * @returns {Promise<void>}
440
+ */
441
+ onDisconnectSet(appName, dbURL, path, props) {
442
+ return guard(async () => {
443
+ const db = getCachedDatabaseInstance(appName, dbURL);
444
+ const dbRef = ref(db, path);
445
+ const instance = getCachedOnDisconnectInstance(dbRef);
446
+ const value = props.value;
447
+ await instance.set(value);
448
+ });
449
+ },
450
+
451
+ /**
452
+ * Sets a value to be written to the database on disconnect with a priority.
453
+ * @param {string} appName - The app name.
454
+ * @param {string} dbURL - The database URL.
455
+ * @param {string} path - The path.
456
+ * @param {object} props - The properties, including value and priority.
457
+ * @returns {Promise<void>}
458
+ */
459
+ onDisconnectSetWithPriority(appName, dbURL, path, props) {
460
+ return guard(async () => {
461
+ const db = getCachedDatabaseInstance(appName, dbURL);
462
+ const dbRef = ref(db, path);
463
+ const instance = getCachedOnDisconnectInstance(dbRef);
464
+ const value = props.value;
465
+ const priority = props.priority;
466
+ await instance.setWithPriority(value, priority);
467
+ });
468
+ },
469
+
470
+ /**
471
+ * Updates the specified path with the provided values on disconnect.
472
+ * @param {string} appName - The app name.
473
+ * @param {string} dbURL - The database URL.
474
+ * @param {string} path - The path.
475
+ * @param {object} props - The properties, including values.
476
+ * @returns {Promise<void>}
477
+ */
478
+ onDisconnectUpdate(appName, dbURL, path, props) {
479
+ return guard(async () => {
480
+ const db = getCachedDatabaseInstance(appName, dbURL);
481
+ const dbRef = ref(db, path);
482
+ const instance = getCachedOnDisconnectInstance(dbRef);
483
+ const values = props.values;
484
+ await instance.update(values);
485
+ });
486
+ },
487
+
488
+ /**
489
+ * Transaction
490
+ */
491
+
492
+ transactionStart(appName, dbURL, path, transactionId, applyLocally, userExecutor) {
493
+ return guard(async () => {
494
+ const db = getCachedDatabaseInstance(appName, dbURL);
495
+ const dbRef = ref(db, path);
496
+
497
+ try {
498
+ const { committed, snapshot } = await runTransaction(dbRef, userExecutor, {
499
+ applyLocally,
500
+ });
501
+
502
+ const event = {
503
+ body: {
504
+ committed,
505
+ type: 'complete',
506
+ snapshot: snapshotToObject(snapshot),
507
+ },
508
+ appName,
509
+ id: transactionId,
510
+ eventName: 'database_transaction_event',
511
+ };
512
+
513
+ emitEvent('database_transaction_event', event);
514
+ } catch (e) {
515
+ const event = {
516
+ body: {
517
+ committed: false,
518
+ type: 'error',
519
+ error: getDatabaseWebError(e),
520
+ },
521
+ appName,
522
+ id: transactionId,
523
+ eventName: 'database_transaction_event',
524
+ };
525
+
526
+ emitEvent('database_transaction_event', event);
527
+ }
528
+ });
529
+ },
530
+
531
+ /**
532
+ * Commits the transaction with the specified updates.
533
+ * @param {string} appName - The app name.
534
+ * @param {string} dbURL - The database URL.
535
+ * @param {string} transactionId - The transaction ID.
536
+ * @param {object} updates - The updates.
537
+ * @returns {Promise<void>}
538
+ */
539
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
540
+ async transactionTryCommit(appName, dbURL, transactionId, updates) {
541
+ // We don't need to implement this as for 'Other' platforms
542
+ // we pass the users transaction function to the Firebase JS SDK directly.
543
+ throw new Error('Not implemented');
544
+ },
545
+ };
@@ -0,0 +1,71 @@
1
+ import {
2
+ query,
3
+ orderByKey,
4
+ orderByPriority,
5
+ orderByValue,
6
+ orderByChild,
7
+ limitToLast,
8
+ limitToFirst,
9
+ endAt,
10
+ endBefore,
11
+ startAt,
12
+ startAfter,
13
+ } from '@react-native-firebase/app/lib/internal/web/firebaseDatabase';
14
+
15
+ export function getQueryInstance(dbRef, modifiers) {
16
+ const constraints = [];
17
+
18
+ for (const modifier of modifiers) {
19
+ const { type, name } = modifier;
20
+
21
+ if (type === 'orderBy') {
22
+ switch (name) {
23
+ case 'orderByKey':
24
+ constraints.push(orderByKey());
25
+ break;
26
+ case 'orderByPriority':
27
+ constraints.push(orderByPriority());
28
+ break;
29
+ case 'orderByValue':
30
+ constraints.push(orderByValue());
31
+ break;
32
+ case 'orderByChild':
33
+ constraints.push(orderByChild(modifier.key));
34
+ break;
35
+ }
36
+ }
37
+
38
+ if (type === 'limit') {
39
+ const { value } = modifier;
40
+
41
+ switch (name) {
42
+ case 'limitToLast':
43
+ constraints.push(limitToLast(value));
44
+ break;
45
+ case 'limitToFirst':
46
+ constraints.push(limitToFirst(value));
47
+ break;
48
+ }
49
+ }
50
+
51
+ if (type === 'filter') {
52
+ const { key, value } = modifier;
53
+
54
+ switch (name) {
55
+ case 'endAt':
56
+ constraints.push(endAt(value, key));
57
+ break;
58
+ case 'endBefore':
59
+ constraints.push(endBefore(value, key));
60
+ break;
61
+ case 'startAt':
62
+ constraints.push(startAt(value, key));
63
+ break;
64
+ case 'startAfter':
65
+ constraints.push(startAfter(value, key));
66
+ break;
67
+ }
68
+ }
69
+ }
70
+ return query(dbRef, ...constraints);
71
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-native-firebase/database",
3
- "version": "20.1.0",
3
+ "version": "20.2.1",
4
4
  "author": "Invertase <oss@invertase.io> (http://invertase.io)",
5
5
  "description": "React Native Firebase - The Firebase Realtime Database is a cloud-hosted database. Data is stored as JSON and synchronized in realtime to every connected client. React Native Firebase provides native integration with the Android & iOS Firebase SDKs, supporting both realtime data sync and offline capabilities.",
6
6
  "main": "lib/index.js",
@@ -25,10 +25,10 @@
25
25
  "realtome database"
26
26
  ],
27
27
  "peerDependencies": {
28
- "@react-native-firebase/app": "20.1.0"
28
+ "@react-native-firebase/app": "20.2.1"
29
29
  },
30
30
  "publishConfig": {
31
31
  "access": "public"
32
32
  },
33
- "gitHead": "99819b9cef23ac46080cbffe50cc85083305d04c"
33
+ "gitHead": "2c787c2dbefbefcc637018e1e5d74a73b39600ab"
34
34
  }