Skip to content

Commit c83ccfb

Browse files
committed
Added childKeys, forEach, map, reverseMap to firebase database snapshot/ref
1 parent 3ef3ce7 commit c83ccfb

File tree

4 files changed

+71
-89
lines changed

4 files changed

+71
-89
lines changed

Diff for: android/src/main/java/io/fullstack/firestack/FirestackDatabase.java

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.util.Iterator;
77
import java.util.List;
88
import java.util.ListIterator;
9+
import java.util.ArrayList;
910
import java.util.Map;
1011
import android.net.Uri;
1112

Diff for: android/src/main/java/io/fullstack/firestack/FirestackUtils.java

+17
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import com.facebook.react.bridge.Arguments;
1313
import com.facebook.react.bridge.Callback;
1414
import com.facebook.react.bridge.WritableMap;
15+
import com.facebook.react.bridge.WritableArray;
1516
import com.facebook.react.bridge.ReadableMap;
1617

1718
import com.facebook.react.bridge.ReadableArray;
@@ -83,6 +84,10 @@ public static WritableMap dataSnapshotToMap(String name,
8384
data.putMap("value", valueMap);
8485
}
8586

87+
// Child keys
88+
WritableArray childKeys = FirestackUtils.getChildKeys(dataSnapshot);
89+
data.putArray("childKeys", childKeys);
90+
8691
Object priority = dataSnapshot.getPriority();
8792
if (priority == null) {
8893
data.putString("priority", null);
@@ -146,6 +151,18 @@ public static <Any> Any castSnapshotValue(DataSnapshot snapshot) {
146151
}
147152
}
148153

154+
public static WritableArray getChildKeys(DataSnapshot snapshot) {
155+
WritableArray childKeys = Arguments.createArray();
156+
157+
if (snapshot.hasChildren()) {
158+
for (DataSnapshot child : snapshot.getChildren()) {
159+
childKeys.pushString(child.getKey());
160+
}
161+
}
162+
163+
return childKeys;
164+
}
165+
149166
public static Map<String, Object> recursivelyDeconstructReadableMap(ReadableMap readableMap) {
150167
ReadableMapKeySetIterator iterator = readableMap.keySetIterator();
151168
Map<String, Object> deconstructedMap = new HashMap<>();

Diff for: ios/Firestack/FirestackDatabase.m

+35-88
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ - (FIRDatabaseQuery *) getQueryWithModifiers:(NSArray *) modifiers
4242
{
4343
FIRDatabaseReference *rootRef = [self getRef];
4444
FIRDatabaseQuery *query = [rootRef queryOrderedByKey];
45-
45+
4646
for (NSString *str in modifiers) {
4747
if ([str isEqualToString:@"orderByKey"]) {
4848
query = [rootRef queryOrderedByKey];
@@ -107,7 +107,7 @@ - (FIRDatabaseQuery *) getQueryWithModifiers:(NSArray *) modifiers
107107
}
108108
}
109109
}
110-
110+
111111
return query;
112112
}
113113

@@ -141,7 +141,7 @@ - (void) removeEventHandler:(NSString *) name
141141
{
142142
FIRDatabaseReference *ref = [self getRef];
143143
int eventType = [self eventTypeFromName:name];
144-
144+
145145
switch (eventType) {
146146
case FIRDataEventTypeValue:
147147
[ref removeObserverWithHandle:self.childValueHandler];
@@ -198,7 +198,7 @@ - (NSArray *) listenerKeys
198198
- (int) eventTypeFromName:(NSString *)name
199199
{
200200
int eventType = FIRDataEventTypeValue;
201-
201+
202202
if ([name isEqualToString:DATABASE_VALUE_EVENT]) {
203203
eventType = FIRDataEventTypeValue;
204204
} else if ([name isEqualToString:DATABASE_CHILD_ADDED_EVENT]) {
@@ -240,7 +240,7 @@ @implementation FirestackDatabase
240240
RCT_EXPORT_METHOD(enablePersistence:(BOOL) enable
241241
callback:(RCTResponseSenderBlock) callback)
242242
{
243-
243+
244244
BOOL isEnabled = [FIRDatabase database].persistenceEnabled;
245245
if ( isEnabled != enable) {
246246
[FIRDatabase database].persistenceEnabled = enable;
@@ -267,7 +267,7 @@ @implementation FirestackDatabase
267267
callback:(RCTResponseSenderBlock) callback)
268268
{
269269
FIRDatabaseReference *ref = [self getRefAtPath:path];
270-
270+
271271
[ref setValue:value withCompletionBlock:^(NSError * _Nullable error, FIRDatabaseReference * _Nonnull ref) {
272272
if (error != nil) {
273273
// Error handling
@@ -286,7 +286,7 @@ @implementation FirestackDatabase
286286
callback:(RCTResponseSenderBlock) callback)
287287
{
288288
FIRDatabaseReference *ref = [self getRefAtPath:path];
289-
289+
290290
[ref updateChildValues:value withCompletionBlock:^(NSError * _Nullable error, FIRDatabaseReference * _Nonnull ref) {
291291
if (error != nil) {
292292
// Error handling
@@ -322,10 +322,10 @@ @implementation FirestackDatabase
322322
callback:(RCTResponseSenderBlock) callback)
323323
{
324324
FIRDatabaseReference *ref = [[self getRefAtPath:path] childByAutoId];
325-
325+
326326
NSURL *url = [NSURL URLWithString:ref.URL];
327327
NSString *newPath = [url path];
328-
328+
329329
if ([props count] > 0) {
330330
[ref setValue:props withCompletionBlock:^(NSError * _Nullable error, FIRDatabaseReference * _Nonnull ref) {
331331
if (error != nil) {
@@ -370,12 +370,12 @@ @implementation FirestackDatabase
370370
@"snapshot": props
371371
}];
372372
};
373-
373+
374374
id errorBlock = ^(NSError * _Nonnull error) {
375375
NSLog(@"Error onDBEvent: %@", [error debugDescription]);
376376
[self getAndSendDatabaseError:error withPath: path];
377377
};
378-
378+
379379
int eventType = [r eventTypeFromName:eventName];
380380
FIRDatabaseHandle handle = [query observeEventType:eventType
381381
withBlock:withBlock
@@ -405,7 +405,7 @@ @implementation FirestackDatabase
405405
FirestackDBReference *r = [self getDBHandle:path];
406406
int eventType = [r eventTypeFromName:name];
407407
FIRDatabaseQuery *ref = [r getQueryWithModifiers:modifiers];
408-
408+
409409
[ref observeSingleEventOfType:eventType
410410
withBlock:^(FIRDataSnapshot * _Nonnull snapshot) {
411411
NSDictionary *props = [self snapshotToDict:snapshot];
@@ -440,7 +440,7 @@ @implementation FirestackDatabase
440440
}
441441

442442
// [self saveDBHandle:path dbRef:r];
443-
443+
444444
callback(@[[NSNull null], @{
445445
@"result": @"success",
446446
@"path": path,
@@ -454,7 +454,7 @@ @implementation FirestackDatabase
454454
callback:(RCTResponseSenderBlock) callback)
455455
{
456456
FIRDatabaseReference *ref = [self getRefAtPath:path];
457-
457+
458458
[ref onDisconnectSetValue:props
459459
withCompletionBlock:^(NSError * _Nullable error, FIRDatabaseReference * _Nonnull ref) {
460460
if (error != nil) {
@@ -543,73 +543,6 @@ - (FIRDatabaseReference *) getRefAtPath:(NSString *) str
543543
return [r getRef];
544544
}
545545

546-
- (FIRDatabaseQuery *) getQueryAtPathWithModifiers:(NSString *) str
547-
modifiers:(NSArray *) modifiers
548-
{
549-
FIRDatabaseReference *rootRef = [self getRefAtPath:str];
550-
551-
FIRDatabaseQuery *query = [rootRef queryOrderedByKey];
552-
553-
for (NSString *str in modifiers) {
554-
if ([str isEqualToString:@"orderByKey"]) {
555-
query = [rootRef queryOrderedByKey];
556-
} else if ([str isEqualToString:@"orderByPriority"]) {
557-
query = [rootRef queryOrderedByPriority];
558-
} else if ([str isEqualToString:@"orderByValue"]) {
559-
query = [rootRef queryOrderedByValue];
560-
} else if ([str containsString:@"orderByChild"]) {
561-
NSArray *args = [str componentsSeparatedByString:@":"];
562-
NSString *key = args[1];
563-
query = [rootRef queryOrderedByChild:key];
564-
} else if ([str containsString:@"limitToLast"]) {
565-
NSArray *args = [str componentsSeparatedByString:@":"];
566-
NSString *key = args[1];
567-
NSUInteger limit = key.integerValue;
568-
query = [query queryLimitedToLast:limit];
569-
} else if ([str containsString:@"limitToFirst"]) {
570-
NSArray *args = [str componentsSeparatedByString:@":"];
571-
NSString *key = args[1];
572-
NSUInteger limit = key.integerValue;
573-
query = [query queryLimitedToFirst:limit];
574-
} else if ([str containsString:@"equalTo"]) {
575-
NSArray *args = [str componentsSeparatedByString:@":"];
576-
NSString *value = args[1];
577-
NSString *key = args[2];
578-
579-
if (key == nil) {
580-
query = [query queryEqualToValue:value];
581-
} else {
582-
query = [query queryEqualToValue:value
583-
childKey:key];
584-
}
585-
} else if ([str containsString:@"endAt"]) {
586-
NSArray *args = [str componentsSeparatedByString:@":"];
587-
NSString *value = args[1];
588-
NSString *key = args[2];
589-
590-
if (key == nil) {
591-
query = [query queryEndingAtValue:value];
592-
} else {
593-
query = [query queryEndingAtValue:value
594-
childKey:key];
595-
}
596-
} else if ([str containsString:@"startAt"]) {
597-
NSArray *args = [str componentsSeparatedByString:@":"];
598-
NSString *value = args[1];
599-
NSString *key = args[2];
600-
601-
if (key == nil) {
602-
query = [query queryStartingAtValue:value];
603-
} else {
604-
query = [query queryStartingAtValue:value
605-
childKey:key];
606-
}
607-
}
608-
}
609-
610-
return query;
611-
}
612-
613546
// Handles
614547
- (NSDictionary *) storedDBHandles
615548
{
@@ -623,7 +556,7 @@ - (FirestackDBReference *) getDBHandle:(NSString *) path
623556
{
624557
NSDictionary *stored = [self storedDBHandles];
625558
FirestackDBReference *r = [stored objectForKey:path];
626-
559+
627560
if (r == nil) {
628561
r = [[FirestackDBReference alloc] initWithPath:path];
629562
[self saveDBHandle:path dbRef:r];
@@ -639,15 +572,15 @@ - (void) saveDBHandle:(NSString *) path
639572
FirestackDBReference *r = [stored objectForKey:path];
640573
[r cleanup];
641574
}
642-
575+
643576
[stored setObject:dbRef forKey:path];
644577
self._DBHandles = stored;
645578
}
646579

647580
- (void) removeDBHandle:(NSString *) path
648581
{
649582
NSMutableDictionary *stored = [[self storedDBHandles] mutableCopy];
650-
583+
651584
FirestackDBReference *r = [stored objectForKey:path];
652585
if (r != nil) {
653586
[r cleanup];
@@ -662,12 +595,26 @@ - (NSDictionary *) snapshotToDict:(FIRDataSnapshot *) snapshot
662595
[dict setValue:snapshot.key forKey:@"key"];
663596
NSDictionary *val = snapshot.value;
664597
[dict setObject:val forKey:@"value"];
665-
598+
599+
// Snapshot ordering
600+
NSMutableArray *childKeys = [NSMutableArray array];
601+
if (snapshot.childrenCount > 0) {
602+
// Since JS does not respect object ordering of keys
603+
// we keep a list of the keys and their ordering
604+
// in the snapshot event
605+
NSEnumerator *children = [snapshot children];
606+
FIRDataSnapshot *child;
607+
while(child = [children nextObject]) {
608+
[childKeys addObject:child.key];
609+
}
610+
}
611+
612+
[dict setObject:childKeys forKey:@"childKeys"];
666613
[dict setValue:@(snapshot.hasChildren) forKey:@"hasChildren"];
667614
[dict setValue:@(snapshot.exists) forKey:@"exists"];
668615
[dict setValue:@(snapshot.childrenCount) forKey:@"childrenCount"];
669616
[dict setValue:snapshot.priority forKey:@"priority"];
670-
617+
671618
return dict;
672619
}
673620

@@ -683,7 +630,7 @@ - (NSDictionary *) getAndSendDatabaseError:(NSError *) error
683630
sendJSEvent:DATABASE_ERROR_EVENT
684631
title:DATABASE_ERROR_EVENT
685632
props: evt];
686-
633+
687634
return evt;
688635
}
689636

@@ -709,4 +656,4 @@ - (void) sendJSEvent:(NSString *)type
709656
}
710657
}
711658

712-
@end
659+
@end

Diff for: lib/modules/database.js

+18-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class DataSnapshot {
1616
static exists:boolean;
1717
static hasChildren:boolean;
1818
static childrenCount:Number;
19+
static childKeys:String[];
1920

2021
constructor(ref, snapshot) {
2122
this.ref = ref;
@@ -25,11 +26,27 @@ class DataSnapshot {
2526
this.priority = snapshot.priority;
2627
this.hasChildren = snapshot.hasChildren || false;
2728
this.childrenCount = snapshot.childrenCount || 0;
29+
this.childKeys = snapshot.childKeys || [];
2830
}
2931

3032
val() {
3133
return this.value;
3234
}
35+
36+
forEach(fn) {
37+
(this.childKeys || [])
38+
.forEach(key => fn(this.value[key]))
39+
}
40+
41+
map(fn) {
42+
let arr = [];
43+
this.forEach(item => arr.push(fn(item)))
44+
return arr;
45+
}
46+
47+
reverseMap(fn) {
48+
return this.map(fn).reverse();
49+
}
3350
}
3451

3552
class DatabaseOnDisconnect {
@@ -497,4 +514,4 @@ export class Database extends Base {
497514
}
498515
}
499516

500-
export default Database
517+
export default Database

0 commit comments

Comments
 (0)