@react-native-firebase/database 20.0.0 → 20.2.0

Sign up to get free protection for your applications and to get access to all the features.
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.0](https://github.com/invertase/react-native-firebase/compare/v20.1.0...v20.2.0) (2024-07-15)
7
+
8
+ ### Features
9
+
10
+ - **other:** Add Database support ([#7887](https://github.com/invertase/react-native-firebase/issues/7887)) ([fbb773a](https://github.com/invertase/react-native-firebase/commit/fbb773a87c167bdc92265fe261aeb777d4660cd7))
11
+
12
+ ### Bug Fixes
13
+
14
+ - **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))
15
+
16
+ ## [20.1.0](https://github.com/invertase/react-native-firebase/compare/v20.0.0...v20.1.0) (2024-06-04)
17
+
18
+ **Note:** Version bump only for package @react-native-firebase/database
19
+
6
20
  ## [20.0.0](https://github.com/invertase/react-native-firebase/compare/v19.3.0...v20.0.0) (2024-05-20)
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.0.0';
2
+ module.exports = '20.2.0';
@@ -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.0.0",
3
+ "version": "20.2.0",
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.0.0"
28
+ "@react-native-firebase/app": "20.2.0"
29
29
  },
30
30
  "publishConfig": {
31
31
  "access": "public"
32
32
  },
33
- "gitHead": "b6079dd09ed1f6e47dc782df0d98c5479bfc0cd4"
33
+ "gitHead": "82c50138d07e673213cd8dee5ce9a2f9b5656649"
34
34
  }