2
0
mirror of synced 2025-01-13 15:46:53 +00:00

[ios][database] linting fixes + now detects if pod installed (makes the pod an optional dependency)

This commit is contained in:
Salakar 2017-05-25 16:00:12 +01:00
parent eba23bad15
commit 18e65b697f
2 changed files with 198 additions and 268 deletions

@ -1,7 +1,6 @@
#ifndef RNFirebaseDatabase_h #ifndef RNFirebaseDatabase_h
#define RNFirebaseDatabase_h #define RNFirebaseDatabase_h
#import "Firebase.h"
#if __has_include(<React/RCTEventEmitter.h>) #if __has_include(<React/RCTEventEmitter.h>)
#import <React/RCTEventEmitter.h> #import <React/RCTEventEmitter.h>
#else // Compatibility for RN version < 0.40 #else // Compatibility for RN version < 0.40
@ -13,14 +12,18 @@
#import "RCTBridgeModule.h" #import "RCTBridgeModule.h"
#endif #endif
@interface RNFirebaseDatabase : RCTEventEmitter <RCTBridgeModule> { #if __has_include(<FirebaseDatabase/FIRDatabase.h>)
#import "Firebase.h"
}
@interface RNFirebaseDatabase : RCTEventEmitter <RCTBridgeModule> {}
@property NSMutableDictionary *dbReferences; @property NSMutableDictionary *dbReferences;
@property NSMutableDictionary *transactions; @property NSMutableDictionary *transactions;
@property dispatch_queue_t transactionQueue; @property dispatch_queue_t transactionQueue;
@end @end
#else
@interface RNFirebaseDatabase : RCTEventEmitter <RCTBridgeModule> {}
@end
#endif
#endif #endif

@ -2,24 +2,23 @@
#import "RNFirebaseDatabase.h" #import "RNFirebaseDatabase.h"
#import "RNFirebaseEvents.h" #import "RNFirebaseEvents.h"
#if __has_include(<FirebaseDatabase/FIRDatabase.h>)
@interface RNFirebaseDBReference : NSObject @interface RNFirebaseDBReference : NSObject
@property RCTEventEmitter *emitter; @property RCTEventEmitter *emitter;
@property FIRDatabaseQuery *query; @property FIRDatabaseQuery *query;
@property NSNumber *refId; @property NSNumber *refId;
@property NSString *path; @property NSString *path;
@property NSMutableDictionary *listeners; @property NSMutableDictionary *listeners;
+ (NSDictionary *) snapshotToDict:(FIRDataSnapshot *) snapshot;
+ (NSDictionary *)snapshotToDict:(FIRDataSnapshot *)snapshot;
@end @end
@implementation RNFirebaseDBReference @implementation RNFirebaseDBReference
- (id) initWithPathAndModifiers:(RCTEventEmitter *) emitter - (id)initWithPathAndModifiers:(RCTEventEmitter *)emitter database:(FIRDatabase *)database refId:(NSNumber *)refId path:(NSString *)path modifiers:(NSArray *)modifiers {
database:(FIRDatabase *) database
refId:(NSNumber *) refId
path:(NSString *) path
modifiers:(NSArray *) modifiers
{
self = [super init]; self = [super init];
if (self) { if (self) {
_emitter = emitter; _emitter = emitter;
@ -31,80 +30,48 @@
return self; return self;
} }
- (void) addEventHandler:(NSNumber *) listenerId - (void)addEventHandler:(NSNumber *)listenerId eventName:(NSString *)eventName {
eventName:(NSString *) eventName if (!_listeners[listenerId]) {
{ id withBlock = ^(FIRDataSnapshot *_Nonnull snapshot) {
if (![_listeners objectForKey:listenerId]) {
id withBlock = ^(FIRDataSnapshot * _Nonnull snapshot) {
NSDictionary *props = [RNFirebaseDBReference snapshotToDict:snapshot]; NSDictionary *props = [RNFirebaseDBReference snapshotToDict:snapshot];
[self sendJSEvent:DATABASE_DATA_EVENT [self sendJSEvent:DATABASE_DATA_EVENT title:eventName props:@{@"eventName": eventName, @"refId": _refId, @"listenerId": listenerId, @"path": _path, @"snapshot": props}];
title:eventName
props: @{
@"eventName": eventName,
@"refId": _refId,
@"listenerId": listenerId,
@"path": _path,
@"snapshot": props
}];
}; };
id errorBlock = ^(NSError * _Nonnull error) { id errorBlock = ^(NSError *_Nonnull error) {
NSLog(@"Error onDBEvent: %@", [error debugDescription]); NSLog(@"Error onDBEvent: %@", [error debugDescription]);
[self removeEventHandler:listenerId eventName:eventName]; [self removeEventHandler:listenerId eventName:eventName];
[self getAndSendDatabaseError:error [self getAndSendDatabaseError:error listenerId:listenerId];
listenerId:listenerId];
}; };
int eventType = [self eventTypeFromName:eventName]; int eventType = [self eventTypeFromName:eventName];
FIRDatabaseHandle handle = [_query observeEventType:eventType FIRDatabaseHandle handle = [_query observeEventType:eventType withBlock:withBlock withCancelBlock:errorBlock];
withBlock:withBlock _listeners[listenerId] = @(handle);
withCancelBlock:errorBlock];
[_listeners setObject:@(handle) forKey:listenerId];
} else { } else {
NSLog(@"Warning Trying to add duplicate listener for refId: %@ listenerId: %@", _refId, listenerId); NSLog(@"Warning Trying to add duplicate listener for refId: %@ listenerId: %@", _refId, listenerId);
} }
} }
- (void) addSingleEventHandler:(RCTResponseSenderBlock) callback - (void)addSingleEventHandler:(RCTResponseSenderBlock)callback {
{ [_query observeSingleEventOfType:FIRDataEventTypeValue withBlock:^(FIRDataSnapshot *_Nonnull snapshot) {
[_query observeSingleEventOfType:FIRDataEventTypeValue NSDictionary *props = [RNFirebaseDBReference snapshotToDict:snapshot];
withBlock:^(FIRDataSnapshot * _Nonnull snapshot) { callback(@[[NSNull null], @{@"eventName": @"value", @"path": _path, @"refId": _refId, @"snapshot": props}]);
NSDictionary *props = [RNFirebaseDBReference snapshotToDict:snapshot]; } withCancelBlock:^(NSError *_Nonnull error) {
callback(@[[NSNull null], @{ NSLog(@"Error onDBEventOnce: %@", [error debugDescription]);
@"eventName": @"value", callback(@[@{@"eventName": DATABASE_ERROR_EVENT, @"path": _path, @"refId": _refId, @"code": @([error code]), @"details": [error debugDescription], @"message": [error localizedDescription], @"description": [error description]}]);
@"path": _path, }];
@"refId": _refId,
@"snapshot": props
}]);
}
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 - (void)removeEventHandler:(NSNumber *)listenerId eventName:(NSString *)eventName {
eventName:(NSString *) eventName FIRDatabaseHandle handle = (FIRDatabaseHandle) [_listeners[listenerId] integerValue];
{
FIRDatabaseHandle handle = [[_listeners objectForKey:listenerId] integerValue];
if (handle) { if (handle) {
[_listeners removeObjectForKey:listenerId]; [_listeners removeObjectForKey:listenerId];
[_query removeObserverWithHandle:handle]; [_query removeObserverWithHandle:handle];
} }
} }
+ (NSDictionary *) snapshotToDict:(FIRDataSnapshot *) snapshot + (NSDictionary *)snapshotToDict:(FIRDataSnapshot *)snapshot {
{
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:snapshot.key forKey:@"key"]; [dict setValue:snapshot.key forKey:@"key"];
NSDictionary *val = snapshot.value; NSDictionary *val = snapshot.value;
[dict setObject:val forKey:@"value"]; dict[@"value"] = val;
// Snapshot ordering // Snapshot ordering
NSMutableArray *childKeys = [NSMutableArray array]; NSMutableArray *childKeys = [NSMutableArray array];
if (snapshot.childrenCount > 0) { if (snapshot.childrenCount > 0) {
@ -113,11 +80,11 @@
// in the snapshot event // in the snapshot event
NSEnumerator *children = [snapshot children]; NSEnumerator *children = [snapshot children];
FIRDataSnapshot *child; FIRDataSnapshot *child;
while(child = [children nextObject]) { while (child = [children nextObject]) {
[childKeys addObject:child.key]; [childKeys addObject:child.key];
} }
} }
[dict setObject:childKeys forKey:@"childKeys"]; dict[@"childKeys"] = childKeys;
[dict setValue:@(snapshot.hasChildren) forKey:@"hasChildren"]; [dict setValue:@(snapshot.hasChildren) forKey:@"hasChildren"];
[dict setValue:@(snapshot.exists) forKey:@"exists"]; [dict setValue:@(snapshot.exists) forKey:@"exists"];
[dict setValue:@(snapshot.childrenCount) forKey:@"childrenCount"]; [dict setValue:@(snapshot.childrenCount) forKey:@"childrenCount"];
@ -125,24 +92,12 @@
return dict; return dict;
} }
- (NSDictionary *) getAndSendDatabaseError:(NSError *) error - (NSDictionary *)getAndSendDatabaseError:(NSError *)error listenerId:(NSNumber *)listenerId {
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]};
{
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 { @try {
[_emitter sendEventWithName:DATABASE_ERROR_EVENT body:event]; [_emitter sendEventWithName:DATABASE_ERROR_EVENT body:event];
} } @catch (NSException *err) {
@catch (NSException *err) {
NSLog(@"An error occurred in getAndSendDatabaseError: %@", [err debugDescription]); NSLog(@"An error occurred in getAndSendDatabaseError: %@", [err debugDescription]);
NSLog(@"Tried to send: %@ with %@", DATABASE_ERROR_EVENT, event); NSLog(@"Tried to send: %@ with %@", DATABASE_ERROR_EVENT, event);
} }
@ -150,19 +105,16 @@
return event; return event;
} }
- (void) sendJSEvent:(NSString *)type title:(NSString *)title props:(NSDictionary *)props { - (void)sendJSEvent:(NSString *)type title:(NSString *)title props:(NSDictionary *)props {
@try { @try {
[_emitter sendEventWithName:type body:@{ @"eventName": title, @"body": props }]; [_emitter sendEventWithName:type body:@{@"eventName": title, @"body": props}];
} @catch (NSException *err) { } @catch (NSException *err) {
NSLog(@"An error occurred in sendJSEvent: %@", [err debugDescription]); NSLog(@"An error occurred in sendJSEvent: %@", [err debugDescription]);
NSLog(@"Tried to send: %@ with %@", title, props); NSLog(@"Tried to send: %@ with %@", title, props);
} }
} }
- (FIRDatabaseQuery *) buildQueryAtPathWithModifiers:(FIRDatabase*) database - (FIRDatabaseQuery *)buildQueryAtPathWithModifiers:(FIRDatabase *)database path:(NSString *)path modifiers:(NSArray *)modifiers {
path:(NSString*) path
modifiers:(NSArray *) modifiers
{
FIRDatabaseQuery *query = [[database reference] child:path]; FIRDatabaseQuery *query = [[database reference] child:path];
for (NSDictionary *modifier in modifiers) { for (NSDictionary *modifier in modifiers) {
@ -187,8 +139,8 @@
query = [query queryLimitedToFirst:limit]; query = [query queryLimitedToFirst:limit];
} }
} else if ([type isEqualToString:@"filter"]) { } else if ([type isEqualToString:@"filter"]) {
NSString* valueType = [modifier valueForKey:@"valueType"]; NSString *valueType = [modifier valueForKey:@"valueType"];
NSString* key = [modifier valueForKey:@"key"]; NSString *key = [modifier valueForKey:@"key"];
id value = [self getIdValue:[modifier valueForKey:@"value"] type:valueType]; id value = [self getIdValue:[modifier valueForKey:@"value"] type:valueType];
if ([name isEqualToString:@"equalTo"]) { if ([name isEqualToString:@"equalTo"]) {
if (key != nil) { if (key != nil) {
@ -215,25 +167,21 @@
return query; return query;
} }
- (id) getIdValue:(NSString *) value - (id)getIdValue:(NSString *)value type:(NSString *)type {
type:(NSString *) type
{
if ([type isEqualToString:@"number"]) { if ([type isEqualToString:@"number"]) {
return [NSNumber numberWithDouble:value.doubleValue]; return @(value.doubleValue);
} else if ([type isEqualToString:@"boolean"]) { } else if ([type isEqualToString:@"boolean"]) {
return [NSNumber numberWithBool:value.boolValue]; return @(value.boolValue);
} else { } else {
return value; return value;
} }
} }
- (BOOL) hasListeners - (BOOL)hasListeners {
{
return [[_listeners allKeys] count] > 0; return [[_listeners allKeys] count] > 0;
} }
- (int) eventTypeFromName:(NSString *)name - (int)eventTypeFromName:(NSString *)name {
{
int eventType = FIRDataEventTypeValue; int eventType = FIRDataEventTypeValue;
if ([name isEqualToString:DATABASE_VALUE_EVENT]) { if ([name isEqualToString:DATABASE_VALUE_EVENT]) {
@ -254,10 +202,9 @@
@implementation RNFirebaseDatabase @implementation RNFirebaseDatabase
RCT_EXPORT_MODULE();
RCT_EXPORT_MODULE(RNFirebaseDatabase); - (id)init {
- (id) init {
self = [super init]; self = [super init];
if (self != nil) { if (self != nil) {
_dbReferences = [[NSMutableDictionary alloc] init]; _dbReferences = [[NSMutableDictionary alloc] init];
@ -267,73 +214,76 @@ RCT_EXPORT_MODULE(RNFirebaseDatabase);
return self; return self;
} }
- (void) sendTransactionEvent:(NSString *)type body:(id)body { - (void)sendTransactionEvent:(NSString *)type body:(id)body {
@try { @try {
[self sendEventWithName:type body:body]; [self sendEventWithName:type body:body];
} @catch (NSException *err) { } @catch (NSException *err) {
NSLog(@"An error occurred in sendJSEvent: %@", [err debugDescription]); NSLog(@"An error occurred in sendJSEvent: %@", [err debugDescription]);
NSLog(@"Tried to send: %@ with %@", type, body); NSLog(@"Tried to send: %@ with %@", type, body);
} }
} }
RCT_EXPORT_METHOD(startTransaction:(NSString *) path identifier:(NSString *) identifier applyLocally:(BOOL) applyLocally) { RCT_EXPORT_METHOD(startTransaction:
(NSString *) path
identifier:
(NSString *) identifier
applyLocally:
(BOOL) applyLocally) {
dispatch_async(_transactionQueue, ^{ dispatch_async(_transactionQueue, ^{
NSMutableDictionary *transactionState = [NSMutableDictionary new]; NSMutableDictionary *transactionState = [NSMutableDictionary new];
dispatch_semaphore_t sema = dispatch_semaphore_create(0); dispatch_semaphore_t sema = dispatch_semaphore_create(0);
[transactionState setObject:sema forKey:@"semaphore"]; [transactionState setObject:sema forKey:@"semaphore"];
FIRDatabaseReference *ref = [self getPathRef:path]; FIRDatabaseReference *ref = [self getPathRef:path];
[ref runTransactionBlock:^FIRTransactionResult * _Nonnull(FIRMutableData * _Nonnull currentData) { [ref runTransactionBlock:^FIRTransactionResult * _Nonnull(FIRMutableData *
dispatch_barrier_async(_transactionQueue, ^{ _Nonnull currentData) {
[_transactions setValue:transactionState forKey:identifier]; dispatch_barrier_async(_transactionQueue, ^{
[self sendTransactionEvent:DATABASE_TRANSACTION_EVENT body:@{ @"id": identifier, @"type": @"update", @"value": currentData.value }]; [_transactions setValue:transactionState forKey:identifier];
}); [self sendTransactionEvent:DATABASE_TRANSACTION_EVENT body:@{@"id": identifier, @"type": @"update", @"value": currentData.value}];
});
// wait for the js event handler to call tryCommitTransaction // wait for the js event handler to call tryCommitTransaction
// this wait occurs on the Firebase Worker Queue // this wait occurs on the Firebase Worker Queue
// so if the tryCommitTransaction fails to signal the semaphore // so if the tryCommitTransaction fails to signal the semaphore
// no further blocks will be executed by Firebase until the timeout expires // no further blocks will be executed by Firebase until the timeout expires
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, 30 * NSEC_PER_SEC); dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, 30 * NSEC_PER_SEC);
BOOL timedout = dispatch_semaphore_wait(sema, delayTime) != 0; BOOL timedout = dispatch_semaphore_wait(sema, delayTime) != 0;
BOOL abort = [transactionState valueForKey:@"abort"] || timedout; BOOL abort = [transactionState valueForKey:@"abort"] || timedout;
id value = [transactionState valueForKey:@"value"]; id value = [transactionState valueForKey:@"value"];
dispatch_barrier_async(_transactionQueue, ^{ dispatch_barrier_async(_transactionQueue, ^{
[_transactions removeObjectForKey:identifier]; [_transactions removeObjectForKey:identifier];
}); });
if (abort) { if (abort) {
return [FIRTransactionResult abort]; return [FIRTransactionResult abort];
} else { } else {
currentData.value = value; currentData.value = value;
return [FIRTransactionResult successWithValue:currentData]; return [FIRTransactionResult successWithValue:currentData];
} }
} andCompletionBlock:^(NSError * _Nullable databaseError, BOOL committed, FIRDataSnapshot * _Nullable snapshot) { }
andCompletionBlock:
^(NSError *_Nullable databaseError, BOOL committed, FIRDataSnapshot *_Nullable snapshot) {
if (databaseError != nil) { if (databaseError != nil) {
[self sendTransactionEvent:DATABASE_TRANSACTION_EVENT body:@{ [self sendTransactionEvent:DATABASE_TRANSACTION_EVENT body:@{@"id": identifier, @"type": @"error", @"code": @([databaseError code]), @"message": [databaseError description]}];
@"id": identifier,
@"type": @"error",
@"code": [NSNumber numberWithInt:[databaseError code]],
@"message": [databaseError description]
}];
} else { } else {
[self sendTransactionEvent:DATABASE_TRANSACTION_EVENT body:@{ [self sendTransactionEvent:DATABASE_TRANSACTION_EVENT body:@{@"id": identifier, @"type": @"complete", @"committed": @(committed), @"snapshot": [RNFirebaseDBReference snapshotToDict:snapshot],}];
@"id": identifier,
@"type": @"complete",
@"committed": @(committed),
@"snapshot": [RNFirebaseDBReference snapshotToDict:snapshot],
}];
} }
} withLocalEvents:applyLocally]; }
withLocalEvents:
applyLocally];
}); });
} }
RCT_EXPORT_METHOD(tryCommitTransaction:(NSString *) identifier withData:(NSDictionary *) data) { RCT_EXPORT_METHOD(tryCommitTransaction:
(NSString *) identifier
withData:
(NSDictionary *) data) {
__block NSMutableDictionary *transactionState; __block NSMutableDictionary *transactionState;
dispatch_sync(_transactionQueue, ^{ dispatch_sync(_transactionQueue, ^{
transactionState = [_transactions objectForKey: identifier]; transactionState = _transactions[identifier];
}); });
if (!transactionState) { if (!transactionState) {
@ -355,68 +305,73 @@ RCT_EXPORT_METHOD(tryCommitTransaction:(NSString *) identifier withData:(NSDicti
dispatch_semaphore_signal(sema); dispatch_semaphore_signal(sema);
} }
RCT_EXPORT_METHOD(enablePersistence:(BOOL) enable RCT_EXPORT_METHOD(enablePersistence:
callback:(RCTResponseSenderBlock) callback) (BOOL) enable
{ callback:
(RCTResponseSenderBlock) callback) {
BOOL isEnabled = [FIRDatabase database].persistenceEnabled; BOOL isEnabled = [FIRDatabase database].persistenceEnabled;
if ( isEnabled != enable) { if (isEnabled != enable) {
@try { @try {
[FIRDatabase database].persistenceEnabled = enable; [FIRDatabase database].persistenceEnabled = enable;
} @catch (NSException *exception) { } @catch (NSException *exception) {
// do nothing - for RN packager reloads // do nothing - for RN packager reloads
} }
} }
callback(@[[NSNull null], @{ callback(@[[NSNull null], @{@"result": @"success"}]);
@"result": @"success"
}]);
} }
RCT_EXPORT_METHOD(keepSynced:(NSString *) path RCT_EXPORT_METHOD(keepSynced:
withEnable:(BOOL) enable (NSString *) path
callback:(RCTResponseSenderBlock) callback) withEnable:
{ (BOOL) enable
callback:
(RCTResponseSenderBlock) callback) {
FIRDatabaseReference *ref = [self getPathRef:path]; FIRDatabaseReference *ref = [self getPathRef:path];
[ref keepSynced:enable]; [ref keepSynced:enable];
callback(@[[NSNull null], @{ callback(@[[NSNull null], @{@"status": @"success", @"path": path}]);
@"status": @"success",
@"path": path
}]);
} }
RCT_EXPORT_METHOD(set:(NSString *) path RCT_EXPORT_METHOD(set:
data:(NSDictionary *)data (NSString *) path
callback:(RCTResponseSenderBlock) callback) data:
{ (NSDictionary *) data
callback:
(RCTResponseSenderBlock) callback) {
FIRDatabaseReference *ref = [self getPathRef:path]; FIRDatabaseReference *ref = [self getPathRef:path];
[ref setValue:[data valueForKey:@"value"] withCompletionBlock:^(NSError * _Nullable error, FIRDatabaseReference * _Nonnull ref) { [ref setValue:[data valueForKey:@"value"] withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
[self handleCallback:@"set" callback:callback databaseError:error]; [self handleCallback:@"set" callback:callback databaseError:error];
}]; }];
} }
RCT_EXPORT_METHOD(update:(NSString *) path RCT_EXPORT_METHOD(update:
value:(NSDictionary *)value (NSString *) path
callback:(RCTResponseSenderBlock) callback) value:
{ (NSDictionary *) value
callback:
(RCTResponseSenderBlock) callback) {
FIRDatabaseReference *ref = [self getPathRef:path]; FIRDatabaseReference *ref = [self getPathRef:path];
[ref updateChildValues:value withCompletionBlock:^(NSError * _Nullable error, FIRDatabaseReference * _Nonnull ref) { [ref updateChildValues:value withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
[self handleCallback:@"update" callback:callback databaseError:error]; [self handleCallback:@"update" callback:callback databaseError:error];
}]; }];
} }
RCT_EXPORT_METHOD(remove:(NSString *) path RCT_EXPORT_METHOD(remove:
callback:(RCTResponseSenderBlock) callback) (NSString *) path
{ callback:
(RCTResponseSenderBlock) callback) {
FIRDatabaseReference *ref = [self getPathRef:path]; FIRDatabaseReference *ref = [self getPathRef:path];
[ref removeValueWithCompletionBlock:^(NSError * _Nullable error, FIRDatabaseReference * _Nonnull ref) { [ref removeValueWithCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
[self handleCallback:@"remove" callback:callback databaseError:error]; [self handleCallback:@"remove" callback:callback databaseError:error];
}]; }];
} }
RCT_EXPORT_METHOD(push:(NSString *) path RCT_EXPORT_METHOD(push:
data:(NSDictionary *) data (NSString *) path
callback:(RCTResponseSenderBlock) callback) data:
{ (NSDictionary *) data
callback:
(RCTResponseSenderBlock) callback) {
FIRDatabaseReference *ref = [self getPathRef:path]; FIRDatabaseReference *ref = [self getPathRef:path];
FIRDatabaseReference *newRef = [ref childByAutoId]; FIRDatabaseReference *newRef = [ref childByAutoId];
@ -424,64 +379,52 @@ RCT_EXPORT_METHOD(push:(NSString *) path
NSString *newPath = [url path]; NSString *newPath = [url path];
if ([data count] > 0) { if ([data count] > 0) {
[newRef setValue:[data valueForKey:@"value"] withCompletionBlock:^(NSError * _Nullable error, FIRDatabaseReference * _Nonnull ref) { [newRef setValue:[data valueForKey:@"value"] withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
if (error != nil) { if (error != nil) {
// Error handling // Error handling
NSDictionary *evt = @{ NSDictionary *evt = @{@"code": @([error code]), @"details": [error debugDescription], @"message": [error localizedDescription], @"description": [error description]};
@"code": @([error code]),
@"details": [error debugDescription],
@"message": [error localizedDescription],
@"description": [error description]
};
callback(@[evt]); callback(@[evt]);
} else { } else {
callback(@[[NSNull null], @{ callback(@[[NSNull null], @{@"status": @"success", @"ref": newPath}]);
@"status": @"success",
@"ref": newPath
}]);
} }
}]; }];
} else { } else {
callback(@[[NSNull null], @{ callback(@[[NSNull null], @{@"status": @"success", @"ref": newPath}]);
@"status": @"success",
@"ref": newPath
}]);
} }
} }
RCT_EXPORT_METHOD(on:(nonnull NSNumber *) refId RCT_EXPORT_METHOD(on:
path:(NSString *) path (nonnull
modifiers:(NSArray *) modifiers NSNumber *) refId
listenerId:(nonnull NSNumber *) listenerId path:(NSString *) path
name:(NSString *) eventName modifiers:(NSArray *) modifiers
callback:(RCTResponseSenderBlock) callback) listenerId:(nonnull NSNumber *) listenerId
{ name:(NSString *) eventName
callback:(RCTResponseSenderBlock) callback) {
RNFirebaseDBReference *ref = [self getDBHandle:refId path:path modifiers:modifiers]; RNFirebaseDBReference *ref = [self getDBHandle:refId path:path modifiers:modifiers];
[ref addEventHandler:listenerId eventName:eventName]; [ref addEventHandler:listenerId eventName:eventName];
callback(@[[NSNull null], @{ callback(@[[NSNull null], @{@"status": @"success", @"refId": refId, @"handle": path}]);
@"status": @"success",
@"refId": refId,
@"handle": path
}]);
} }
RCT_EXPORT_METHOD(once:(nonnull NSNumber *) refId RCT_EXPORT_METHOD(once:
path:(NSString *) path (nonnull
modifiers:(NSArray *) modifiers NSNumber *) refId
eventName:(NSString *) eventName path:(NSString *) path
callback:(RCTResponseSenderBlock) callback) modifiers:(NSArray *) modifiers
{ eventName:(NSString *) eventName
callback:(RCTResponseSenderBlock) callback) {
RNFirebaseDBReference *ref = [self getDBHandle:refId path:path modifiers:modifiers]; RNFirebaseDBReference *ref = [self getDBHandle:refId path:path modifiers:modifiers];
[ref addSingleEventHandler:callback]; [ref addSingleEventHandler:callback];
} }
RCT_EXPORT_METHOD(off:(nonnull NSNumber *) refId RCT_EXPORT_METHOD(off:
listeners:(NSArray *) listeners (nonnull
callback:(RCTResponseSenderBlock) callback) NSNumber *) refId
{ listeners:(NSArray *) listeners
RNFirebaseDBReference *ref = [_dbReferences objectForKey:refId]; callback:(RCTResponseSenderBlock) callback) {
RNFirebaseDBReference *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"];
@ -492,92 +435,70 @@ RCT_EXPORT_METHOD(off:(nonnull NSNumber *) refId
} }
} }
} }
callback(@[[NSNull null], @{ callback(@[[NSNull null], @{@"status": @"success", @"refId": refId,}]);
@"status": @"success",
@"refId": refId,
}]);
} }
// On disconnect // On disconnect
RCT_EXPORT_METHOD(onDisconnectSet:(NSString *) path RCT_EXPORT_METHOD(onDisconnectSet:
props:(NSDictionary *) props (NSString *) path
callback:(RCTResponseSenderBlock) callback) props:
{ (NSDictionary *) props
callback:
(RCTResponseSenderBlock) callback) {
FIRDatabaseReference *ref = [self getPathRef:path]; FIRDatabaseReference *ref = [self getPathRef:path];
[ref onDisconnectSetValue:props[@"value"] [ref onDisconnectSetValue:props[@"value"] withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
withCompletionBlock:^(NSError * _Nullable error, FIRDatabaseReference * _Nonnull ref) { [self handleCallback:@"onDisconnectSetObject" callback:callback databaseError:error];
[self handleCallback:@"onDisconnectSetObject" callback:callback databaseError:error]; }];
}];
} }
RCT_EXPORT_METHOD(onDisconnectRemove:(NSString *) path RCT_EXPORT_METHOD(onDisconnectRemove:
callback:(RCTResponseSenderBlock) callback) (NSString *) path
{ callback:
(RCTResponseSenderBlock) callback) {
FIRDatabaseReference *ref = [self getPathRef:path]; FIRDatabaseReference *ref = [self getPathRef:path];
[ref onDisconnectRemoveValueWithCompletionBlock:^(NSError * _Nullable error, FIRDatabaseReference * _Nonnull ref) { [ref onDisconnectRemoveValueWithCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
[self handleCallback:@"onDisconnectRemove" callback:callback databaseError:error]; [self handleCallback:@"onDisconnectRemove" callback:callback databaseError:error];
}]; }];
} }
RCT_EXPORT_METHOD(onDisconnectCancel:
RCT_EXPORT_METHOD(onDisconnectCancel:(NSString *) path (NSString *) path
callback:(RCTResponseSenderBlock) callback) callback:
{ (RCTResponseSenderBlock) callback) {
FIRDatabaseReference *ref = [self getPathRef:path]; FIRDatabaseReference *ref = [self getPathRef:path];
[ref cancelDisconnectOperationsWithCompletionBlock:^(NSError * _Nullable error, FIRDatabaseReference * _Nonnull ref) { [ref cancelDisconnectOperationsWithCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
[self handleCallback:@"onDisconnectCancel" callback:callback databaseError:error]; [self handleCallback:@"onDisconnectCancel" callback:callback databaseError:error];
}]; }];
} }
RCT_EXPORT_METHOD(goOffline) RCT_EXPORT_METHOD(goOffline) {
{
[FIRDatabase database].goOffline; [FIRDatabase database].goOffline;
} }
RCT_EXPORT_METHOD(goOnline) RCT_EXPORT_METHOD(goOnline) {
{
[FIRDatabase database].goOnline; [FIRDatabase database].goOnline;
} }
- (FIRDatabaseReference *) getPathRef:(NSString *) path - (FIRDatabaseReference *)getPathRef:(NSString *)path {
{
return [[[FIRDatabase database] reference] child:path]; return [[[FIRDatabase database] reference] child:path];
} }
- (void) handleCallback:(NSString *) methodName - (void)handleCallback:(NSString *)methodName callback:(RCTResponseSenderBlock)callback databaseError:(NSError *)databaseError {
callback:(RCTResponseSenderBlock) callback
databaseError:(NSError *) databaseError
{
if (databaseError != nil) { if (databaseError != nil) {
NSDictionary *evt = @{ NSDictionary *evt = @{@"code": @([databaseError code]), @"details": [databaseError debugDescription], @"message": [databaseError localizedDescription], @"description": [databaseError description]};
@"code": [NSNumber numberWithInt:[databaseError code]],
@"details": [databaseError debugDescription],
@"message": [databaseError localizedDescription],
@"description": [databaseError description]
};
callback(@[evt]); callback(@[evt]);
} else { } else {
callback(@[[NSNull null], @{ callback(@[[NSNull null], @{@"status": @"success", @"method": methodName}]);
@"status": @"success",
@"method": methodName
}]);
} }
} }
- (RNFirebaseDBReference *) getDBHandle:(NSNumber *) refId - (RNFirebaseDBReference *)getDBHandle:(NSNumber *)refId path:(NSString *)path modifiers:(NSArray *)modifiers {
path:(NSString *) path RNFirebaseDBReference *ref = _dbReferences[refId];
modifiers:(NSArray *) modifiers
{
RNFirebaseDBReference *ref = [_dbReferences objectForKey:refId];
if (ref == nil) { if (ref == nil) {
ref = [[RNFirebaseDBReference alloc] initWithPathAndModifiers:self ref = [[RNFirebaseDBReference alloc] initWithPathAndModifiers:self database:[FIRDatabase database] refId:refId path:path modifiers:modifiers];
database:[FIRDatabase database] _dbReferences[refId] = ref;
refId:refId
path:path
modifiers:modifiers];
[_dbReferences setObject:ref forKey:refId];
} }
return ref; return ref;
} }
@ -587,5 +508,11 @@ RCT_EXPORT_METHOD(goOnline)
return @[DATABASE_DATA_EVENT, DATABASE_ERROR_EVENT, DATABASE_TRANSACTION_EVENT]; return @[DATABASE_DATA_EVENT, DATABASE_ERROR_EVENT, DATABASE_TRANSACTION_EVENT];
} }
@end @end
#else
@implementation RNFirebaseDatabase
RCT_EXPORT_MODULE();
RCT_EXPORT_METHOD(nativeSDKMissing) {}
@end
#endif