Skip to content

Commit

Permalink
fix(database): set priority on child snapshot if available (#7897)
Browse files Browse the repository at this point in the history
  • Loading branch information
russellwheatley authored Jul 15, 2024
1 parent 753b16e commit 9028ae4
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@
import com.facebook.react.bridge.*;
import com.google.firebase.database.DataSnapshot;
import com.google.firebase.database.MutableData;
import java.util.HashMap;
import javax.annotation.Nullable;

public class ReactNativeFirebaseDatabaseCommon {
private static final String TAG = "DatabaseCommon";
private static final String childPrioritiesKey = "childPriorities";
private static final String childKeysKey = "childKeys";

/**
* @param promise
Expand Down Expand Up @@ -61,12 +64,13 @@ public static WritableMap snapshotWithPreviousChildToMap(
*/
public static WritableMap snapshotToMap(DataSnapshot dataSnapshot) {
WritableMap snapshot = Arguments.createMap();

HashMap<String, Object> childProperties = getChildProperties(dataSnapshot);
snapshot.putString("key", dataSnapshot.getKey());
snapshot.putBoolean("exists", dataSnapshot.exists());
snapshot.putBoolean("hasChildren", dataSnapshot.hasChildren());
snapshot.putDouble("childrenCount", dataSnapshot.getChildrenCount());
snapshot.putArray("childKeys", getChildKeys(dataSnapshot));
snapshot.putArray(childKeysKey, (ReadableArray) childProperties.get(childKeysKey));
snapshot.putMap(childPrioritiesKey, (WritableMap) childProperties.get(childPrioritiesKey));
mapPutValue("priority", dataSnapshot.getPriority(), snapshot);

if (!dataSnapshot.hasChildren()) {
Expand Down Expand Up @@ -369,15 +373,29 @@ private static <Any> WritableMap buildMap(MutableData mutableData) {
* @param snapshot
* @return
*/
public static WritableArray getChildKeys(DataSnapshot snapshot) {
public static HashMap<String, Object> getChildProperties(DataSnapshot snapshot) {
WritableArray childKeys = Arguments.createArray();

WritableMap childPriorities = Arguments.createMap();
HashMap<String, Object> childProperties = new HashMap<>();
if (snapshot.hasChildren()) {
for (DataSnapshot child : snapshot.getChildren()) {
childKeys.pushString(child.getKey());

Object priority = child.getPriority();
// Priority can be String, Double or null
if (priority instanceof String) {
childPriorities.putString(child.getKey(), (String) priority);
} else if (priority instanceof Double) {
childPriorities.putDouble(child.getKey(), (Double) priority);
} else if (priority == null) {
childPriorities.putNull(child.getKey());
}
}
}

return childKeys;
childProperties.put(childKeysKey, childKeys);
childProperties.put(childPrioritiesKey, childPriorities);

return childProperties;
}
}
54 changes: 54 additions & 0 deletions packages/database/e2e/snapshot/snapshot.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,32 @@ describe('database()...snapshot', function () {
snapshot1.val().should.equal('foobar');
snapshot2.val().should.eql(jet.contextify(CONTENT.TYPES.object));
});

it('should return the correct priority for the child snapshots', async function () {
if (Platform.other) {
// TODO - remove once "other" is fully integrated
this.skip();
}
const ref = firebase.database().ref(TEST_PATH).child('get-priority-children');
const child1 = ref.child('child1');
const child2 = ref.child('child2');
const child3 = ref.child('child3');

await Promise.all([
child1.set({ foo: 'bar' }),
child2.set({ foo: 'bar' }),
child3.set({ foo: 'bar' }),
]);

await child1.setPriority(1);
await child2.setPriority(2);
await child3.setPriority(3);

const snapshot = await ref.once('value');
snapshot.child('child1').getPriority().should.equal(1);
snapshot.child('child2').getPriority().should.equal(2);
snapshot.child('child3').getPriority().should.equal(3);
});
});

describe('modular', function () {
Expand Down Expand Up @@ -530,5 +556,33 @@ describe('database()...snapshot', function () {
snapshot1.val().should.equal('foobar');
snapshot2.val().should.eql(jet.contextify(CONTENT.TYPES.object));
});

it('should return the correct priority for the child snapshots', async function () {
if (Platform.other) {
// TODO - remove once "other" is fully integrated
this.skip();
}
const { getDatabase, ref, child, set, setPriority, get } = databaseModular;
const reference = child(ref(getDatabase(), TEST_PATH), 'get-priority-children-mod');

const child1 = child(reference, 'child1');
const child2 = child(reference, 'child2');
const child3 = child(reference, 'child3');

await Promise.all([
set(child1, { foo: 'bar' }),
set(child2, { foo: 'bar' }),
set(child3, { foo: 'bar' }),
]);

await setPriority(child1, 1);
await setPriority(child2, 2);
await setPriority(child3, 3);

const snapshot = await get(reference);
snapshot.child('child1').getPriority().should.equal(1);
snapshot.child('child2').getPriority().should.equal(2);
snapshot.child('child3').getPriority().should.equal(3);
});
});
});
13 changes: 10 additions & 3 deletions packages/database/ios/RNFBDatabase/RNFBDatabaseCommon.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@
NSString *const DATABASE_LOGGING_ENABLED = @"firebase_database_logging_enabled";
NSString *const DATABASE_PERSISTENCE_CACHE_SIZE = @"firebase_database_persistence_cache_size_bytes";

NSString *const childPrioritiesKey = @"childPriorities";
NSString *const childKeysKey = @"childKeys";

@implementation RNFBDatabaseCommon

+ (void)load {
Expand Down Expand Up @@ -250,28 +253,32 @@ + (NSDictionary *)snapshotToDictionary:(FIRDataSnapshot *)dataSnapshot {
} else {
[snapshot setValue:[NSNull null] forKey:@"key"];
}
NSMutableDictionary *childProperties = [self getSnapshotChildProperties:dataSnapshot];
[snapshot setValue:@(dataSnapshot.exists) forKey:@"exists"];
[snapshot setValue:@(dataSnapshot.hasChildren) forKey:@"hasChildren"];
[snapshot setValue:@(dataSnapshot.childrenCount) forKey:@"childrenCount"];
[snapshot setValue:[self getSnapshotChildKeys:dataSnapshot] forKey:@"childKeys"];
[snapshot setValue:childProperties[childKeysKey] forKey:childKeysKey];
[snapshot setValue:childProperties[childPrioritiesKey] forKey:childPrioritiesKey];
[snapshot setValue:dataSnapshot.priority forKey:@"priority"];
[snapshot setValue:dataSnapshot.value forKey:@"value"];

return snapshot;
}

+ (NSMutableArray *)getSnapshotChildKeys:(FIRDataSnapshot *)dataSnapshot {
+ (NSMutableDictionary *)getSnapshotChildProperties:(FIRDataSnapshot *)dataSnapshot {
NSMutableArray *childKeys = [NSMutableArray array];
NSMutableDictionary *childPriorities = [[NSMutableDictionary alloc] init];
if (dataSnapshot.childrenCount > 0) {
NSEnumerator *children = [dataSnapshot children];
FIRDataSnapshot *child;
child = [children nextObject];
while (child) {
[childKeys addObject:child.key];
[childPriorities setValue:child.priority forKey:child.key];
child = [children nextObject];
}
}
return childKeys;
return @{childKeysKey : childKeys, childPrioritiesKey : childPriorities};
}

@end
16 changes: 15 additions & 1 deletion packages/database/lib/DatabaseDataSnapshot.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@
*
*/

import { isArray, isFunction, isObject, isString } from '@react-native-firebase/app/lib/common';
import {
isArray,
isFunction,
isObject,
isString,
isNumber,
} from '@react-native-firebase/app/lib/common';
import { deepGet } from '@react-native-firebase/app/lib/common/deeps';

export default class DatabaseDataSnapshot {
Expand Down Expand Up @@ -61,11 +67,19 @@ export default class DatabaseDataSnapshot {

const childRef = this._ref.child(path);

let childPriority = null;
if (this._snapshot.childPriorities) {
const childPriorityValue = this._snapshot.childPriorities[childRef.key];
if (isString(childPriorityValue) || isNumber(childPriorityValue)) {
childPriority = childPriorityValue;
}
}
return new DatabaseDataSnapshot(childRef, {
value,
key: childRef.key,
exists: value !== null,
childKeys: isObject(value) ? Object.keys(value) : [],
priority: childPriority,
});
}

Expand Down

0 comments on commit 9028ae4

Please sign in to comment.