[ios][database] Refactor RNFirebaseDatabaseReference
This commit is contained in:
parent
7f4882abe6
commit
27453ac31a
@ -1,206 +1,9 @@
|
|||||||
#import "RNFirebaseDatabase.h"
|
#import "RNFirebaseDatabase.h"
|
||||||
#import "RNFirebaseEvents.h"
|
|
||||||
#import "Firebase.h"
|
|
||||||
|
|
||||||
#if __has_include(<FirebaseDatabase/FIRDatabase.h>)
|
#if __has_include(<FirebaseDatabase/FIRDatabase.h>)
|
||||||
|
#import "RNFirebaseDatabaseReference.h"
|
||||||
@interface RNFirebaseDBReference : NSObject
|
#import "RNFirebaseEvents.h"
|
||||||
@property RCTEventEmitter *emitter;
|
#import "Firebase.h"
|
||||||
@property FIRDatabaseQuery *query;
|
|
||||||
@property NSNumber *refId;
|
|
||||||
@property NSString *path;
|
|
||||||
@property NSMutableDictionary *listeners;
|
|
||||||
|
|
||||||
+ (NSDictionary *)snapshotToDict:(FIRDataSnapshot *)snapshot;
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation RNFirebaseDBReference
|
|
||||||
|
|
||||||
|
|
||||||
- (id)initWithPathAndModifiers:(RCTEventEmitter *)emitter database:(FIRDatabase *)database refId:(NSNumber *)refId path:(NSString *)path modifiers:(NSArray *)modifiers {
|
|
||||||
self = [super init];
|
|
||||||
if (self) {
|
|
||||||
_emitter = emitter;
|
|
||||||
_refId = refId;
|
|
||||||
_path = path;
|
|
||||||
_query = [self buildQueryAtPathWithModifiers:database path:path modifiers:modifiers];
|
|
||||||
_listeners = [[NSMutableDictionary alloc] init];
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)addEventHandler:(NSNumber *)listenerId eventName:(NSString *)eventName {
|
|
||||||
if (!_listeners[listenerId]) {
|
|
||||||
id andPreviousSiblingKeyWithBlock = ^(FIRDataSnapshot *_Nonnull snapshot, NSString *_Nullable previousChildName) {
|
|
||||||
NSDictionary *props = [RNFirebaseDBReference snapshotToDict:snapshot];
|
|
||||||
[self sendJSEvent:DATABASE_DATA_EVENT title:eventName props:@{@"eventName": eventName, @"refId": _refId, @"listenerId": listenerId, @"path": _path, @"snapshot": props, @"previousChildName": previousChildName != nil ? previousChildName : [NSNull null]}];
|
|
||||||
};
|
|
||||||
id errorBlock = ^(NSError *_Nonnull error) {
|
|
||||||
NSLog(@"Error onDBEvent: %@", [error debugDescription]);
|
|
||||||
[self removeEventHandler:listenerId eventName:eventName];
|
|
||||||
[self getAndSendDatabaseError:error listenerId:listenerId];
|
|
||||||
};
|
|
||||||
int eventType = [self eventTypeFromName:eventName];
|
|
||||||
FIRDatabaseHandle handle = [_query observeEventType:eventType andPreviousSiblingKeyWithBlock:andPreviousSiblingKeyWithBlock withCancelBlock:errorBlock];
|
|
||||||
_listeners[listenerId] = @(handle);
|
|
||||||
} else {
|
|
||||||
NSLog(@"Warning Trying to add duplicate listener for refId: %@ listenerId: %@", _refId, listenerId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)addSingleEventHandler:(NSString *)eventName callback:(RCTResponseSenderBlock)callback {
|
|
||||||
FIRDataEventType firDataEventType = (FIRDataEventType)[self eventTypeFromName:eventName];
|
|
||||||
|
|
||||||
[_query observeSingleEventOfType:firDataEventType andPreviousSiblingKeyWithBlock:^(FIRDataSnapshot *_Nonnull snapshot, NSString *_Nullable previousChildName) {
|
|
||||||
NSDictionary *props = [RNFirebaseDBReference snapshotToDict:snapshot];
|
|
||||||
callback(@[[NSNull null], @{@"eventName": eventName, @"path": _path, @"refId": _refId, @"snapshot": props, @"previousChildName": previousChildName != nil ? previousChildName : [NSNull null]}]);
|
|
||||||
} withCancelBlock:^(NSError *_Nonnull error) {
|
|
||||||
NSLog(@"Error onDBEventOnce: %@", [error debugDescription]);
|
|
||||||
callback(@[@{@"eventName": DATABASE_ERROR_EVENT, @"path": _path, @"refId": _refId, @"code": @([error code]), @"details": [error debugDescription], @"message": [error localizedDescription], @"description": [error description]}]);
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)removeEventHandler:(NSNumber *)listenerId eventName:(NSString *)eventName {
|
|
||||||
FIRDatabaseHandle handle = (FIRDatabaseHandle) [_listeners[listenerId] integerValue];
|
|
||||||
if (handle) {
|
|
||||||
[_listeners removeObjectForKey:listenerId];
|
|
||||||
[_query removeObserverWithHandle:handle];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
+ (NSDictionary *)snapshotToDict:(FIRDataSnapshot *)snapshot {
|
|
||||||
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
|
|
||||||
[dict setValue:snapshot.key forKey:@"key"];
|
|
||||||
NSDictionary *val = snapshot.value;
|
|
||||||
dict[@"value"] = val;
|
|
||||||
// Snapshot ordering
|
|
||||||
NSMutableArray *childKeys = [NSMutableArray array];
|
|
||||||
if (snapshot.childrenCount > 0) {
|
|
||||||
// Since JS does not respect object ordering of keys
|
|
||||||
// we keep a list of the keys and their ordering
|
|
||||||
// in the snapshot event
|
|
||||||
NSEnumerator *children = [snapshot children];
|
|
||||||
FIRDataSnapshot *child;
|
|
||||||
while (child = [children nextObject]) {
|
|
||||||
[childKeys addObject:child.key];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dict[@"childKeys"] = childKeys;
|
|
||||||
[dict setValue:@(snapshot.hasChildren) forKey:@"hasChildren"];
|
|
||||||
[dict setValue:@(snapshot.exists) forKey:@"exists"];
|
|
||||||
[dict setValue:@(snapshot.childrenCount) forKey:@"childrenCount"];
|
|
||||||
[dict setValue:snapshot.priority forKey:@"priority"];
|
|
||||||
return dict;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSDictionary *)getAndSendDatabaseError:(NSError *)error listenerId:(NSNumber *)listenerId {
|
|
||||||
NSDictionary *event = @{@"eventName": DATABASE_ERROR_EVENT, @"path": _path, @"refId": _refId, @"listenerId": listenerId, @"code": @([error code]), @"details": [error debugDescription], @"message": [error localizedDescription], @"description": [error description]};
|
|
||||||
|
|
||||||
@try {
|
|
||||||
[_emitter sendEventWithName:DATABASE_ERROR_EVENT body:event];
|
|
||||||
} @catch (NSException *err) {
|
|
||||||
NSLog(@"An error occurred in getAndSendDatabaseError: %@", [err debugDescription]);
|
|
||||||
NSLog(@"Tried to send: %@ with %@", DATABASE_ERROR_EVENT, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
return event;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)sendJSEvent:(NSString *)type title:(NSString *)title props:(NSDictionary *)props {
|
|
||||||
@try {
|
|
||||||
[_emitter sendEventWithName:type body:@{@"eventName": title, @"body": props}];
|
|
||||||
} @catch (NSException *err) {
|
|
||||||
NSLog(@"An error occurred in sendJSEvent: %@", [err debugDescription]);
|
|
||||||
NSLog(@"Tried to send: %@ with %@", title, props);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (FIRDatabaseQuery *)buildQueryAtPathWithModifiers:(FIRDatabase *)database path:(NSString *)path modifiers:(NSArray *)modifiers {
|
|
||||||
FIRDatabaseQuery *query = [[database reference] child:path];
|
|
||||||
|
|
||||||
for (NSDictionary *modifier in modifiers) {
|
|
||||||
NSString *type = [modifier valueForKey:@"type"];
|
|
||||||
NSString *name = [modifier valueForKey:@"name"];
|
|
||||||
if ([type isEqualToString:@"orderBy"]) {
|
|
||||||
if ([name isEqualToString:@"orderByKey"]) {
|
|
||||||
query = [query queryOrderedByKey];
|
|
||||||
} else if ([name isEqualToString:@"orderByPriority"]) {
|
|
||||||
query = [query queryOrderedByPriority];
|
|
||||||
} else if ([name isEqualToString:@"orderByValue"]) {
|
|
||||||
query = [query queryOrderedByValue];
|
|
||||||
} else if ([name isEqualToString:@"orderByChild"]) {
|
|
||||||
NSString *key = [modifier valueForKey:@"key"];
|
|
||||||
query = [query queryOrderedByChild:key];
|
|
||||||
}
|
|
||||||
} else if ([type isEqualToString:@"limit"]) {
|
|
||||||
int limit = [[modifier valueForKey:@"limit"] integerValue];
|
|
||||||
if ([name isEqualToString:@"limitToLast"]) {
|
|
||||||
query = [query queryLimitedToLast:limit];
|
|
||||||
} else if ([name isEqualToString:@"limitToFirst"]) {
|
|
||||||
query = [query queryLimitedToFirst:limit];
|
|
||||||
}
|
|
||||||
} else if ([type isEqualToString:@"filter"]) {
|
|
||||||
NSString *valueType = [modifier valueForKey:@"valueType"];
|
|
||||||
NSString *key = [modifier valueForKey:@"key"];
|
|
||||||
id value = [self getIdValue:[modifier valueForKey:@"value"] type:valueType];
|
|
||||||
if ([name isEqualToString:@"equalTo"]) {
|
|
||||||
if (key != nil) {
|
|
||||||
query = [query queryEqualToValue:value childKey:key];
|
|
||||||
} else {
|
|
||||||
query = [query queryEqualToValue:value];
|
|
||||||
}
|
|
||||||
} else if ([name isEqualToString:@"endAt"]) {
|
|
||||||
if (key != nil) {
|
|
||||||
query = [query queryEndingAtValue:value childKey:key];
|
|
||||||
} else {
|
|
||||||
query = [query queryEndingAtValue:value];
|
|
||||||
}
|
|
||||||
} else if ([name isEqualToString:@"startAt"]) {
|
|
||||||
if (key != nil) {
|
|
||||||
query = [query queryStartingAtValue:value childKey:key];
|
|
||||||
} else {
|
|
||||||
query = [query queryStartingAtValue:value];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (id)getIdValue:(NSString *)value type:(NSString *)type {
|
|
||||||
if ([type isEqualToString:@"number"]) {
|
|
||||||
return @(value.doubleValue);
|
|
||||||
} else if ([type isEqualToString:@"boolean"]) {
|
|
||||||
return @(value.boolValue);
|
|
||||||
} else {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)hasListeners {
|
|
||||||
return [[_listeners allKeys] count] > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (int)eventTypeFromName:(NSString *)name {
|
|
||||||
int eventType = FIRDataEventTypeValue;
|
|
||||||
|
|
||||||
if ([name isEqualToString:DATABASE_VALUE_EVENT]) {
|
|
||||||
eventType = FIRDataEventTypeValue;
|
|
||||||
} else if ([name isEqualToString:DATABASE_CHILD_ADDED_EVENT]) {
|
|
||||||
eventType = FIRDataEventTypeChildAdded;
|
|
||||||
} else if ([name isEqualToString:DATABASE_CHILD_MODIFIED_EVENT]) {
|
|
||||||
eventType = FIRDataEventTypeChildChanged;
|
|
||||||
} else if ([name isEqualToString:DATABASE_CHILD_REMOVED_EVENT]) {
|
|
||||||
eventType = FIRDataEventTypeChildRemoved;
|
|
||||||
} else if ([name isEqualToString:DATABASE_CHILD_MOVED_EVENT]) {
|
|
||||||
eventType = FIRDataEventTypeChildMoved;
|
|
||||||
}
|
|
||||||
return eventType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
|
|
||||||
@implementation RNFirebaseDatabase
|
@implementation RNFirebaseDatabase
|
||||||
RCT_EXPORT_MODULE();
|
RCT_EXPORT_MODULE();
|
||||||
@ -269,7 +72,7 @@ RCT_EXPORT_METHOD(startTransaction:
|
|||||||
if (databaseError != nil) {
|
if (databaseError != nil) {
|
||||||
[self sendTransactionEvent:DATABASE_TRANSACTION_EVENT body:@{@"id": identifier, @"type": @"error", @"code": @([databaseError code]), @"message": [databaseError description]}];
|
[self sendTransactionEvent:DATABASE_TRANSACTION_EVENT body:@{@"id": identifier, @"type": @"error", @"code": @([databaseError code]), @"message": [databaseError description]}];
|
||||||
} else {
|
} else {
|
||||||
[self sendTransactionEvent:DATABASE_TRANSACTION_EVENT body:@{@"id": identifier, @"type": @"complete", @"committed": @(committed), @"snapshot": [RNFirebaseDBReference snapshotToDict:snapshot],}];
|
[self sendTransactionEvent:DATABASE_TRANSACTION_EVENT body:@{@"id": identifier, @"type": @"complete", @"committed": @(committed), @"snapshot": [RNFirebaseDatabaseReference snapshotToDict:snapshot],}];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
withLocalEvents:
|
withLocalEvents:
|
||||||
@ -404,7 +207,7 @@ RCT_EXPORT_METHOD(on:
|
|||||||
listenerId:(nonnull NSNumber *) listenerId
|
listenerId:(nonnull NSNumber *) listenerId
|
||||||
name:(NSString *) eventName
|
name:(NSString *) eventName
|
||||||
callback:(RCTResponseSenderBlock) callback) {
|
callback:(RCTResponseSenderBlock) callback) {
|
||||||
RNFirebaseDBReference *ref = [self getDBHandle:refId path:path modifiers:modifiers];
|
RNFirebaseDatabaseReference *ref = [self getDBHandle:refId path:path modifiers:modifiers];
|
||||||
[ref addEventHandler:listenerId eventName:eventName];
|
[ref addEventHandler:listenerId eventName:eventName];
|
||||||
callback(@[[NSNull null], @{@"status": @"success", @"refId": refId, @"handle": path}]);
|
callback(@[[NSNull null], @{@"status": @"success", @"refId": refId, @"handle": path}]);
|
||||||
}
|
}
|
||||||
@ -416,7 +219,7 @@ RCT_EXPORT_METHOD(once:
|
|||||||
modifiers:(NSArray *) modifiers
|
modifiers:(NSArray *) modifiers
|
||||||
eventName:(NSString *) eventName
|
eventName:(NSString *) eventName
|
||||||
callback:(RCTResponseSenderBlock) callback) {
|
callback:(RCTResponseSenderBlock) callback) {
|
||||||
RNFirebaseDBReference *ref = [self getDBHandle:refId path:path modifiers:modifiers];
|
RNFirebaseDatabaseReference *ref = [self getDBHandle:refId path:path modifiers:modifiers];
|
||||||
[ref addSingleEventHandler:eventName callback:callback];
|
[ref addSingleEventHandler:eventName callback:callback];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -425,7 +228,7 @@ RCT_EXPORT_METHOD(off:
|
|||||||
NSNumber *) refId
|
NSNumber *) refId
|
||||||
listeners:(NSArray *) listeners
|
listeners:(NSArray *) listeners
|
||||||
callback:(RCTResponseSenderBlock) callback) {
|
callback:(RCTResponseSenderBlock) callback) {
|
||||||
RNFirebaseDBReference *ref = _dbReferences[refId];
|
RNFirebaseDatabaseReference *ref = _dbReferences[refId];
|
||||||
if (ref != nil) {
|
if (ref != nil) {
|
||||||
for (NSDictionary *listener in listeners) {
|
for (NSDictionary *listener in listeners) {
|
||||||
NSNumber *listenerId = [listener valueForKey:@"listenerId"];
|
NSNumber *listenerId = [listener valueForKey:@"listenerId"];
|
||||||
@ -494,11 +297,11 @@ RCT_EXPORT_METHOD(goOnline) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (RNFirebaseDBReference *)getDBHandle:(NSNumber *)refId path:(NSString *)path modifiers:(NSArray *)modifiers {
|
- (RNFirebaseDatabaseReference *)getDBHandle:(NSNumber *)refId path:(NSString *)path modifiers:(NSArray *)modifiers {
|
||||||
RNFirebaseDBReference *ref = _dbReferences[refId];
|
RNFirebaseDatabaseReference *ref = _dbReferences[refId];
|
||||||
|
|
||||||
if (ref == nil) {
|
if (ref == nil) {
|
||||||
ref = [[RNFirebaseDBReference alloc] initWithPathAndModifiers:self database:[FIRDatabase database] refId:refId path:path modifiers:modifiers];
|
ref = [[RNFirebaseDatabaseReference alloc] initWithPathAndModifiers:self database:[FIRDatabase database] refId:refId path:path modifiers:modifiers];
|
||||||
_dbReferences[refId] = ref;
|
_dbReferences[refId] = ref;
|
||||||
}
|
}
|
||||||
return ref;
|
return ref;
|
||||||
|
29
ios/RNFirebase/database/RNFirebaseDatabaseReference.h
Normal file
29
ios/RNFirebase/database/RNFirebaseDatabaseReference.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef RNFirebaseDatabaseReference_h
|
||||||
|
#define RNFirebaseDatabaseReference_h
|
||||||
|
|
||||||
|
#if __has_include(<FirebaseDatabase/FIRDatabase.h>)
|
||||||
|
#import <React/RCTEventEmitter.h>
|
||||||
|
#import "Firebase.h"
|
||||||
|
|
||||||
|
@interface RNFirebaseDatabaseReference : NSObject
|
||||||
|
@property RCTEventEmitter *emitter;
|
||||||
|
@property FIRDatabaseQuery *query;
|
||||||
|
@property NSNumber *refId;
|
||||||
|
@property NSString *path;
|
||||||
|
@property NSMutableDictionary *listeners;
|
||||||
|
|
||||||
|
- (id)initWithPathAndModifiers:(RCTEventEmitter *)emitter database:(FIRDatabase *)database refId:(NSNumber *)refId path:(NSString *)path modifiers:(NSArray *)modifiers;
|
||||||
|
- (void)addEventHandler:(NSNumber *)listenerId eventName:(NSString *)eventName;
|
||||||
|
- (void)addSingleEventHandler:(NSString *)eventName callback:(RCTResponseSenderBlock)callback;
|
||||||
|
- (void)removeEventHandler:(NSNumber *)listenerId eventName:(NSString *)eventName;
|
||||||
|
- (BOOL)hasListeners;
|
||||||
|
+ (NSDictionary *)snapshotToDict:(FIRDataSnapshot *)snapshot;
|
||||||
|
@end
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
@interface RNFirebaseDatabaseReference : NSObject
|
||||||
|
@end
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
195
ios/RNFirebase/database/RNFirebaseDatabaseReference.m
Normal file
195
ios/RNFirebase/database/RNFirebaseDatabaseReference.m
Normal file
@ -0,0 +1,195 @@
|
|||||||
|
#import "RNFirebaseDatabaseReference.h"
|
||||||
|
|
||||||
|
#if __has_include(<FirebaseDatabase/FIRDatabase.h>)
|
||||||
|
#import "RNFirebaseEvents.h"
|
||||||
|
|
||||||
|
@implementation RNFirebaseDatabaseReference
|
||||||
|
|
||||||
|
- (id)initWithPathAndModifiers:(RCTEventEmitter *)emitter database:(FIRDatabase *)database refId:(NSNumber *)refId path:(NSString *)path modifiers:(NSArray *)modifiers {
|
||||||
|
self = [super init];
|
||||||
|
if (self) {
|
||||||
|
_emitter = emitter;
|
||||||
|
_refId = refId;
|
||||||
|
_path = path;
|
||||||
|
_query = [self buildQueryAtPathWithModifiers:database path:path modifiers:modifiers];
|
||||||
|
_listeners = [[NSMutableDictionary alloc] init];
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)addEventHandler:(NSNumber *)listenerId eventName:(NSString *)eventName {
|
||||||
|
if (!_listeners[listenerId]) {
|
||||||
|
id andPreviousSiblingKeyWithBlock = ^(FIRDataSnapshot *_Nonnull snapshot, NSString *_Nullable previousChildName) {
|
||||||
|
NSDictionary *props = [RNFirebaseDatabaseReference snapshotToDict:snapshot];
|
||||||
|
[self sendJSEvent:DATABASE_DATA_EVENT title:eventName props:@{@"eventName": eventName, @"refId": _refId, @"listenerId": listenerId, @"path": _path, @"snapshot": props, @"previousChildName": previousChildName != nil ? previousChildName : [NSNull null]}];
|
||||||
|
};
|
||||||
|
id errorBlock = ^(NSError *_Nonnull error) {
|
||||||
|
NSLog(@"Error onDBEvent: %@", [error debugDescription]);
|
||||||
|
[self removeEventHandler:listenerId eventName:eventName];
|
||||||
|
[self getAndSendDatabaseError:error listenerId:listenerId];
|
||||||
|
};
|
||||||
|
int eventType = [self eventTypeFromName:eventName];
|
||||||
|
FIRDatabaseHandle handle = [_query observeEventType:eventType andPreviousSiblingKeyWithBlock:andPreviousSiblingKeyWithBlock withCancelBlock:errorBlock];
|
||||||
|
_listeners[listenerId] = @(handle);
|
||||||
|
} else {
|
||||||
|
NSLog(@"Warning Trying to add duplicate listener for refId: %@ listenerId: %@", _refId, listenerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)addSingleEventHandler:(NSString *)eventName callback:(RCTResponseSenderBlock)callback {
|
||||||
|
FIRDataEventType firDataEventType = (FIRDataEventType)[self eventTypeFromName:eventName];
|
||||||
|
|
||||||
|
[_query observeSingleEventOfType:firDataEventType andPreviousSiblingKeyWithBlock:^(FIRDataSnapshot *_Nonnull snapshot, NSString *_Nullable previousChildName) {
|
||||||
|
NSDictionary *props = [RNFirebaseDatabaseReference snapshotToDict:snapshot];
|
||||||
|
callback(@[[NSNull null], @{@"eventName": eventName, @"path": _path, @"refId": _refId, @"snapshot": props, @"previousChildName": previousChildName != nil ? previousChildName : [NSNull null]}]);
|
||||||
|
} withCancelBlock:^(NSError *_Nonnull error) {
|
||||||
|
NSLog(@"Error onDBEventOnce: %@", [error debugDescription]);
|
||||||
|
callback(@[@{@"eventName": DATABASE_ERROR_EVENT, @"path": _path, @"refId": _refId, @"code": @([error code]), @"details": [error debugDescription], @"message": [error localizedDescription], @"description": [error description]}]);
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)removeEventHandler:(NSNumber *)listenerId eventName:(NSString *)eventName {
|
||||||
|
FIRDatabaseHandle handle = (FIRDatabaseHandle) [_listeners[listenerId] integerValue];
|
||||||
|
if (handle) {
|
||||||
|
[_listeners removeObjectForKey:listenerId];
|
||||||
|
[_query removeObserverWithHandle:handle];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSDictionary *)snapshotToDict:(FIRDataSnapshot *)snapshot {
|
||||||
|
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
|
||||||
|
[dict setValue:snapshot.key forKey:@"key"];
|
||||||
|
NSDictionary *val = snapshot.value;
|
||||||
|
dict[@"value"] = val;
|
||||||
|
// Snapshot ordering
|
||||||
|
NSMutableArray *childKeys = [NSMutableArray array];
|
||||||
|
if (snapshot.childrenCount > 0) {
|
||||||
|
// Since JS does not respect object ordering of keys
|
||||||
|
// we keep a list of the keys and their ordering
|
||||||
|
// in the snapshot event
|
||||||
|
NSEnumerator *children = [snapshot children];
|
||||||
|
FIRDataSnapshot *child;
|
||||||
|
while (child = [children nextObject]) {
|
||||||
|
[childKeys addObject:child.key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dict[@"childKeys"] = childKeys;
|
||||||
|
[dict setValue:@(snapshot.hasChildren) forKey:@"hasChildren"];
|
||||||
|
[dict setValue:@(snapshot.exists) forKey:@"exists"];
|
||||||
|
[dict setValue:@(snapshot.childrenCount) forKey:@"childrenCount"];
|
||||||
|
[dict setValue:snapshot.priority forKey:@"priority"];
|
||||||
|
return dict;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSDictionary *)getAndSendDatabaseError:(NSError *)error listenerId:(NSNumber *)listenerId {
|
||||||
|
NSDictionary *event = @{@"eventName": DATABASE_ERROR_EVENT, @"path": _path, @"refId": _refId, @"listenerId": listenerId, @"code": @([error code]), @"details": [error debugDescription], @"message": [error localizedDescription], @"description": [error description]};
|
||||||
|
|
||||||
|
@try {
|
||||||
|
[_emitter sendEventWithName:DATABASE_ERROR_EVENT body:event];
|
||||||
|
} @catch (NSException *err) {
|
||||||
|
NSLog(@"An error occurred in getAndSendDatabaseError: %@", [err debugDescription]);
|
||||||
|
NSLog(@"Tried to send: %@ with %@", DATABASE_ERROR_EVENT, event);
|
||||||
|
}
|
||||||
|
|
||||||
|
return event;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)sendJSEvent:(NSString *)type title:(NSString *)title props:(NSDictionary *)props {
|
||||||
|
@try {
|
||||||
|
[_emitter sendEventWithName:type body:@{@"eventName": title, @"body": props}];
|
||||||
|
} @catch (NSException *err) {
|
||||||
|
NSLog(@"An error occurred in sendJSEvent: %@", [err debugDescription]);
|
||||||
|
NSLog(@"Tried to send: %@ with %@", title, props);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (FIRDatabaseQuery *)buildQueryAtPathWithModifiers:(FIRDatabase *)database path:(NSString *)path modifiers:(NSArray *)modifiers {
|
||||||
|
FIRDatabaseQuery *query = [[database reference] child:path];
|
||||||
|
|
||||||
|
for (NSDictionary *modifier in modifiers) {
|
||||||
|
NSString *type = [modifier valueForKey:@"type"];
|
||||||
|
NSString *name = [modifier valueForKey:@"name"];
|
||||||
|
if ([type isEqualToString:@"orderBy"]) {
|
||||||
|
if ([name isEqualToString:@"orderByKey"]) {
|
||||||
|
query = [query queryOrderedByKey];
|
||||||
|
} else if ([name isEqualToString:@"orderByPriority"]) {
|
||||||
|
query = [query queryOrderedByPriority];
|
||||||
|
} else if ([name isEqualToString:@"orderByValue"]) {
|
||||||
|
query = [query queryOrderedByValue];
|
||||||
|
} else if ([name isEqualToString:@"orderByChild"]) {
|
||||||
|
NSString *key = [modifier valueForKey:@"key"];
|
||||||
|
query = [query queryOrderedByChild:key];
|
||||||
|
}
|
||||||
|
} else if ([type isEqualToString:@"limit"]) {
|
||||||
|
int limit = [[modifier valueForKey:@"limit"] integerValue];
|
||||||
|
if ([name isEqualToString:@"limitToLast"]) {
|
||||||
|
query = [query queryLimitedToLast:limit];
|
||||||
|
} else if ([name isEqualToString:@"limitToFirst"]) {
|
||||||
|
query = [query queryLimitedToFirst:limit];
|
||||||
|
}
|
||||||
|
} else if ([type isEqualToString:@"filter"]) {
|
||||||
|
NSString *valueType = [modifier valueForKey:@"valueType"];
|
||||||
|
NSString *key = [modifier valueForKey:@"key"];
|
||||||
|
id value = [self getIdValue:[modifier valueForKey:@"value"] type:valueType];
|
||||||
|
if ([name isEqualToString:@"equalTo"]) {
|
||||||
|
if (key != nil) {
|
||||||
|
query = [query queryEqualToValue:value childKey:key];
|
||||||
|
} else {
|
||||||
|
query = [query queryEqualToValue:value];
|
||||||
|
}
|
||||||
|
} else if ([name isEqualToString:@"endAt"]) {
|
||||||
|
if (key != nil) {
|
||||||
|
query = [query queryEndingAtValue:value childKey:key];
|
||||||
|
} else {
|
||||||
|
query = [query queryEndingAtValue:value];
|
||||||
|
}
|
||||||
|
} else if ([name isEqualToString:@"startAt"]) {
|
||||||
|
if (key != nil) {
|
||||||
|
query = [query queryStartingAtValue:value childKey:key];
|
||||||
|
} else {
|
||||||
|
query = [query queryStartingAtValue:value];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return query;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id)getIdValue:(NSString *)value type:(NSString *)type {
|
||||||
|
if ([type isEqualToString:@"number"]) {
|
||||||
|
return @(value.doubleValue);
|
||||||
|
} else if ([type isEqualToString:@"boolean"]) {
|
||||||
|
return @(value.boolValue);
|
||||||
|
} else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)hasListeners {
|
||||||
|
return [[_listeners allKeys] count] > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (int)eventTypeFromName:(NSString *)name {
|
||||||
|
int eventType = FIRDataEventTypeValue;
|
||||||
|
|
||||||
|
if ([name isEqualToString:DATABASE_VALUE_EVENT]) {
|
||||||
|
eventType = FIRDataEventTypeValue;
|
||||||
|
} else if ([name isEqualToString:DATABASE_CHILD_ADDED_EVENT]) {
|
||||||
|
eventType = FIRDataEventTypeChildAdded;
|
||||||
|
} else if ([name isEqualToString:DATABASE_CHILD_MODIFIED_EVENT]) {
|
||||||
|
eventType = FIRDataEventTypeChildChanged;
|
||||||
|
} else if ([name isEqualToString:DATABASE_CHILD_REMOVED_EVENT]) {
|
||||||
|
eventType = FIRDataEventTypeChildRemoved;
|
||||||
|
} else if ([name isEqualToString:DATABASE_CHILD_MOVED_EVENT]) {
|
||||||
|
eventType = FIRDataEventTypeChildMoved;
|
||||||
|
}
|
||||||
|
return eventType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#else
|
||||||
|
@implementation RNFirebaseDatabase
|
||||||
|
@end
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user