2017-03-09 15:26:28 +00:00
# import "RNFirebaseDatabase.h"
2017-05-25 15:00:12 +00:00
# if __has _include ( < FirebaseDatabase / FIRDatabase . h > )
2017-08-14 10:05:49 +00:00
2017-07-19 15:02:26 +00:00
# import "RNFirebaseDatabaseReference.h"
# import "RNFirebaseEvents.h"
2017-03-25 00:59:27 +00:00
2017-03-09 15:26:28 +00:00
@ implementation RNFirebaseDatabase
2017-05-25 15:00:12 +00:00
RCT_EXPORT _MODULE ( ) ;
2017-03-09 15:26:28 +00:00
2017-08-14 10:05:49 +00:00
// TODO document methods
2017-05-25 15:00:12 +00:00
- ( id ) init {
2017-03-09 15:26:28 +00:00
self = [ super init ] ;
if ( self ! = nil ) {
_dbReferences = [ [ NSMutableDictionary alloc ] init ] ;
2017-03-25 00:59:27 +00:00
_transactions = [ [ NSMutableDictionary alloc ] init ] ;
_transactionQueue = dispatch_queue _create ( "io.invertase.react-native-firebase" , DISPATCH_QUEUE _CONCURRENT ) ;
2017-03-09 15:26:28 +00:00
}
return self ;
}
2017-08-14 10:05:49 +00:00
RCT_EXPORT _METHOD ( goOnline :
( NSString * ) appName ) {
2017-08-02 15:51:00 +00:00
[ [ RNFirebaseDatabase getDatabaseForApp : appName ] goOnline ] ;
2017-03-25 00:59:27 +00:00
}
2017-08-14 10:05:49 +00:00
RCT_EXPORT _METHOD ( goOffline :
( NSString * ) appName ) {
2017-08-02 15:51:00 +00:00
[ [ RNFirebaseDatabase getDatabaseForApp : appName ] goOffline ] ;
}
2017-04-26 16:34:16 +00:00
2017-08-14 10:05:49 +00:00
RCT_EXPORT _METHOD ( setPersistence :
( NSString * ) appName
state :
( BOOL ) state ) {
2017-08-02 15:51:00 +00:00
[ RNFirebaseDatabase getDatabaseForApp : appName ] . persistenceEnabled = state ;
2017-03-25 00:59:27 +00:00
}
2017-08-14 10:05:49 +00:00
RCT_EXPORT _METHOD ( keepSynced :
( NSString * ) appName
refId :
( nonnull
NSNumber * ) refId
path : ( NSString * ) path
modifiers : ( NSArray * ) modifiers
state : ( BOOL ) state ) {
2017-08-05 20:43:53 +00:00
2017-08-14 10:05:49 +00:00
FIRDatabaseQuery * query = [ self getInternalReferenceForApp : appName refId : refId path : path modifiers : modifiers keep : false ] . query ;
2017-08-05 20:43:53 +00:00
[ query keepSynced : state ] ;
2017-08-02 15:51:00 +00:00
}
2017-04-26 16:34:16 +00:00
2017-08-14 10:05:49 +00:00
RCT_EXPORT _METHOD ( transactionTryCommit :
( NSString * ) appName
transactionId :
( nonnull
NSNumber * ) transactionId
updates : ( NSDictionary * ) updates ) {
2017-08-02 15:51:00 +00:00
__block NSMutableDictionary * transactionState ;
2017-08-05 20:43:53 +00:00
2017-03-25 00:59:27 +00:00
dispatch_sync ( _transactionQueue , ^ {
2017-08-02 15:51:00 +00:00
transactionState = _transactions [ transactionId ] ;
2017-03-25 00:59:27 +00:00
} ) ;
2017-08-05 20:43:53 +00:00
2017-03-25 00:59:27 +00:00
if ( ! transactionState ) {
2017-08-02 15:51:00 +00:00
NSLog ( @ "tryCommitTransaction for unknown ID %@" , transactionId ) ;
2017-03-25 00:59:27 +00:00
return ;
}
2017-08-05 20:43:53 +00:00
2017-03-25 00:59:27 +00:00
dispatch_semaphore _t sema = [ transactionState valueForKey : @ "semaphore" ] ;
2017-08-05 20:43:53 +00:00
2017-08-02 15:51:00 +00:00
BOOL abort = [ [ updates valueForKey : @ "abort" ] boolValue ] ;
2017-08-05 20:43:53 +00:00
2017-03-25 00:59:27 +00:00
if ( abort ) {
[ transactionState setValue : @ true forKey : @ "abort" ] ;
} else {
2017-08-02 15:51:00 +00:00
id newValue = [ updates valueForKey : @ "value" ] ;
2017-03-25 00:59:27 +00:00
[ transactionState setValue : newValue forKey : @ "value" ] ;
}
2017-08-05 20:43:53 +00:00
2017-03-25 00:59:27 +00:00
dispatch_semaphore _signal ( sema ) ;
}
2017-08-02 15:51:00 +00:00
2017-08-14 10:05:49 +00:00
RCT_EXPORT _METHOD ( transactionStart :
( NSString * ) appName
path :
( NSString * ) path
transactionId :
( nonnull
NSNumber * ) transactionId
applyLocally : ( BOOL ) applyLocally ) {
2017-08-02 15:51:00 +00:00
dispatch_async ( _transactionQueue , ^ {
NSMutableDictionary * transactionState = [ NSMutableDictionary new ] ;
dispatch_semaphore _t sema = dispatch_semaphore _create ( 0 ) ;
transactionState [ @ "semaphore" ] = sema ;
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appName path : path ] ;
2017-08-05 20:43:53 +00:00
2017-08-02 15:51:00 +00:00
[ ref runTransactionBlock : ^ FIRTransactionResult * _Nonnull ( FIRMutableData *
2017-08-14 10:05:49 +00:00
_Nonnull currentData ) {
dispatch_barrier _async ( _transactionQueue , ^ {
[ _transactions setValue : transactionState forKey : transactionId ] ;
NSDictionary * updateMap = [ self createTransactionUpdateMap : appName transactionId : transactionId updatesData : currentData ] ;
[ self sendEventWithName : DATABASE_TRANSACTION _EVENT body : updateMap ] ;
} ) ;
// wait for the js event handler to call tryCommitTransaction
// this wait occurs on the Firebase Worker Queue
// so if the tryCommitTransaction fails to signal the semaphore
// 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 ) ;
BOOL timedout = dispatch_semaphore _wait ( sema , delayTime ) ! = 0 ;
BOOL abort = [ transactionState valueForKey : @ "abort" ] || timedout ;
id value = [ transactionState valueForKey : @ "value" ] ;
dispatch_barrier _async ( _transactionQueue , ^ {
[ _transactions removeObjectForKey : transactionId ] ;
} ) ;
if ( abort ) {
return [ FIRTransactionResult abort ] ;
} else {
currentData . value = value ;
return [ FIRTransactionResult successWithValue : currentData ] ;
}
}
andCompletionBlock :
^ ( NSError * _Nullable databaseError , BOOL committed , FIRDataSnapshot * _Nullable snapshot ) {
NSDictionary * resultMap = [ self createTransactionResultMap : appName transactionId : transactionId error : databaseError committed : committed snapshot : snapshot ] ;
[ self sendEventWithName : DATABASE_TRANSACTION _EVENT body : resultMap ] ;
2017-05-09 16:20:06 +00:00
}
2017-08-14 10:05:49 +00:00
withLocalEvents :
applyLocally ] ;
2017-08-02 15:51:00 +00:00
} ) ;
}
2017-08-14 10:05:49 +00:00
RCT_EXPORT _METHOD ( onDisconnectSet :
( NSString * ) appName
path :
( NSString * ) path
props :
( NSDictionary * ) props
resolver :
( RCTPromiseResolveBlock ) resolve
rejecter :
( RCTPromiseRejectBlock ) reject ) {
2017-08-02 15:51:00 +00:00
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appName path : path ] ;
[ ref onDisconnectSetValue : props [ @ "value" ] withCompletionBlock : ^ ( NSError * _Nullable error , FIRDatabaseReference * _Nonnull _ref ) {
[ RNFirebaseDatabase handlePromise : resolve rejecter : reject databaseError : error ] ;
} ] ;
}
2017-08-14 10:05:49 +00:00
RCT_EXPORT _METHOD ( onDisconnectUpdate :
( NSString * ) appName
path :
( NSString * ) path
props :
( NSDictionary * ) props
resolver :
( RCTPromiseResolveBlock ) resolve
rejecter :
( RCTPromiseRejectBlock ) reject ) {
2017-08-02 15:51:00 +00:00
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appName path : path ] ;
[ ref onDisconnectUpdateChildValues : props withCompletionBlock : ^ ( NSError * _Nullable error , FIRDatabaseReference * _Nonnull _ref ) {
[ RNFirebaseDatabase handlePromise : resolve rejecter : reject databaseError : error ] ;
} ] ;
}
2017-08-14 10:05:49 +00:00
RCT_EXPORT _METHOD ( onDisconnectRemove :
( NSString * ) appName
path :
( NSString * ) path
resolver :
( RCTPromiseResolveBlock ) resolve
rejecter :
( RCTPromiseRejectBlock ) reject ) {
2017-08-02 15:51:00 +00:00
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appName path : path ] ;
[ ref onDisconnectRemoveValueWithCompletionBlock : ^ ( NSError * _Nullable error , FIRDatabaseReference * _Nonnull _ref ) {
[ RNFirebaseDatabase handlePromise : resolve rejecter : reject databaseError : error ] ;
} ] ;
2017-03-09 15:26:28 +00:00
}
2017-08-14 10:05:49 +00:00
RCT_EXPORT _METHOD ( onDisconnectCancel :
( NSString * ) appName
path :
( NSString * ) path
resolver :
( RCTPromiseResolveBlock ) resolve
rejecter :
( RCTPromiseRejectBlock ) reject ) {
2017-08-02 15:51:00 +00:00
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appName path : path ] ;
[ ref cancelDisconnectOperationsWithCompletionBlock : ^ ( NSError * _Nullable error , FIRDatabaseReference * _Nonnull _ref ) {
[ RNFirebaseDatabase handlePromise : resolve rejecter : reject databaseError : error ] ;
} ] ;
2017-03-09 15:26:28 +00:00
}
2017-08-14 10:05:49 +00:00
RCT_EXPORT _METHOD ( set :
( NSString * ) appName
path :
( NSString * ) path
props :
( NSDictionary * ) props
resolver :
( RCTPromiseResolveBlock ) resolve
rejecter :
( RCTPromiseRejectBlock ) reject ) {
2017-08-02 15:51:00 +00:00
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appName path : path ] ;
[ ref setValue : [ props valueForKey : @ "value" ] withCompletionBlock : ^ ( NSError * _Nullable error , FIRDatabaseReference * _Nonnull _ref ) {
[ RNFirebaseDatabase handlePromise : resolve rejecter : reject databaseError : error ] ;
2017-03-09 15:26:28 +00:00
} ] ;
}
2017-08-14 10:05:49 +00:00
RCT_EXPORT _METHOD ( setPriority :
( NSString * ) appName
path :
( NSString * ) path
priority :
( NSDictionary * ) priority
resolver :
( RCTPromiseResolveBlock ) resolve
rejecter :
( RCTPromiseRejectBlock ) reject ) {
2017-08-02 15:51:00 +00:00
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appName path : path ] ;
2017-08-14 10:05:49 +00:00
[ ref setPriority : [ priority valueForKey : @ "value" ] withCompletionBlock : ^ ( NSError * _Nullable error , FIRDatabaseReference * _Nonnull ref ) {
2017-08-02 15:51:00 +00:00
[ RNFirebaseDatabase handlePromise : resolve rejecter : reject databaseError : error ] ;
2017-07-19 17:18:16 +00:00
} ] ;
}
2017-08-14 10:05:49 +00:00
RCT_EXPORT _METHOD ( setWithPriority :
( NSString * ) appName
path :
( NSString * ) path
data :
( NSDictionary * ) data
priority :
( NSDictionary * ) priority
resolver :
( RCTPromiseResolveBlock ) resolve
rejecter :
( RCTPromiseRejectBlock ) reject ) {
2017-08-02 15:51:00 +00:00
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appName path : path ] ;
2017-08-14 10:05:49 +00:00
[ ref setValue : [ data valueForKey : @ "value" ] andPriority : [ priority valueForKey : @ "value" ] withCompletionBlock : ^ ( NSError * _Nullable error , FIRDatabaseReference * _Nonnull ref ) {
2017-08-02 15:51:00 +00:00
[ RNFirebaseDatabase handlePromise : resolve rejecter : reject databaseError : error ] ;
2017-07-19 17:18:16 +00:00
} ] ;
}
2017-08-14 10:05:49 +00:00
RCT_EXPORT _METHOD ( update :
( NSString * ) appName
path :
( NSString * ) path
props :
( NSDictionary * ) props
resolver :
( RCTPromiseResolveBlock ) resolve
rejecter :
( RCTPromiseRejectBlock ) reject ) {
2017-08-02 15:51:00 +00:00
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appName path : path ] ;
[ ref updateChildValues : props withCompletionBlock : ^ ( NSError * _Nullable error , FIRDatabaseReference * _Nonnull _ref ) {
[ RNFirebaseDatabase handlePromise : resolve rejecter : reject databaseError : error ] ;
2017-03-09 15:26:28 +00:00
} ] ;
}
2017-08-14 10:05:49 +00:00
RCT_EXPORT _METHOD ( remove :
( NSString * ) appName
path :
( NSString * ) path
resolver :
( RCTPromiseResolveBlock ) resolve
rejecter :
( RCTPromiseRejectBlock ) reject ) {
2017-08-02 15:51:00 +00:00
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appName path : path ] ;
2017-05-25 15:00:12 +00:00
[ ref removeValueWithCompletionBlock : ^ ( NSError * _Nullable error , FIRDatabaseReference * _Nonnull _ref ) {
2017-08-02 15:51:00 +00:00
[ RNFirebaseDatabase handlePromise : resolve rejecter : reject databaseError : error ] ;
2017-03-09 15:26:28 +00:00
} ] ;
}
2017-08-14 10:05:49 +00:00
RCT_EXPORT _METHOD ( once :
( NSString * ) appName
refId :
( nonnull
NSNumber * ) refId
path : ( NSString * ) path
modifiers : ( NSArray * ) modifiers
eventName : ( NSString * ) eventName
resolver : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject ) {
2017-08-02 15:51:00 +00:00
RNFirebaseDatabaseReference * ref = [ self getInternalReferenceForApp : appName refId : refId path : path modifiers : modifiers keep : false ] ;
[ ref addSingleEventHandler : eventName resolver : resolve rejecter : reject ] ;
}
/ *
* INTERNALS / UTILS
* /
2017-08-14 10:05:49 +00:00
+ ( void ) handlePromise : ( RCTPromiseResolveBlock ) resolve rejecter : ( RCTPromiseRejectBlock ) reject databaseError : ( NSError * ) databaseError {
2017-08-02 15:51:00 +00:00
if ( databaseError ! = nil ) {
NSDictionary * jsError = [ RNFirebaseDatabase getJSError : databaseError ] ;
reject ( [ jsError valueForKey : @ "code" ] , [ jsError valueForKey : @ "message" ] , databaseError ) ;
2017-03-09 15:26:28 +00:00
} else {
2017-08-02 15:51:00 +00:00
resolve ( [ NSNull null ] ) ;
2017-03-09 15:26:28 +00:00
}
}
2017-08-14 10:05:49 +00:00
+ ( FIRDatabase * ) getDatabaseForApp : ( NSString * ) appName {
2017-08-02 15:51:00 +00:00
FIRApp * app = [ FIRApp appNamed : appName ] ;
return [ FIRDatabase databaseForApp : app ] ;
}
2017-08-14 10:05:49 +00:00
- ( FIRDatabaseReference * ) getReferenceForAppPath : ( NSString * ) appName path : ( NSString * ) path {
2017-08-02 15:51:00 +00:00
return [ [ RNFirebaseDatabase getDatabaseForApp : appName ] referenceWithPath : path ] ;
}
2017-03-09 15:26:28 +00:00
2017-08-14 10:05:49 +00:00
- ( RNFirebaseDatabaseReference * ) getInternalReferenceForApp : ( NSString * ) appName refId : ( NSNumber * ) refId path : ( NSString * ) path modifiers : ( NSArray * ) modifiers keep : ( BOOL ) keep {
2017-08-02 15:51:00 +00:00
RNFirebaseDatabaseReference * ref = _dbReferences [ refId ] ;
2017-08-05 20:43:53 +00:00
2017-08-02 15:51:00 +00:00
if ( ref = = nil ) {
ref = [ [ RNFirebaseDatabaseReference alloc ] initWithPathAndModifiers : self app : appName refId : refId refPath : path modifiers : modifiers ] ;
2017-08-05 20:43:53 +00:00
2017-08-02 15:51:00 +00:00
if ( keep ) {
_dbReferences [ refId ] = ref ;
}
}
return ref ;
}
// TODO : Move to error util for use in other modules
2017-08-14 10:05:49 +00:00
+ ( NSString * ) getMessageWithService : ( NSString * ) message service : ( NSString * ) service fullCode : ( NSString * ) fullCode {
2017-08-02 15:51:00 +00:00
return [ NSString stringWithFormat : @ "%@: %@ (%@)." , service , message , [ fullCode lowercaseString ] ] ;
}
2017-08-14 10:05:49 +00:00
+ ( NSString * ) getCodeWithService : ( NSString * ) service code : ( NSString * ) code {
2017-08-02 15:51:00 +00:00
return [ NSString stringWithFormat : @ "%@/%@" , [ service uppercaseString ] , [ code uppercaseString ] ] ;
}
2017-08-14 10:05:49 +00:00
+ ( NSDictionary * ) getJSError : ( NSError * ) nativeError {
2017-08-02 15:51:00 +00:00
NSMutableDictionary * errorMap = [ [ NSMutableDictionary alloc ] init ] ;
[ errorMap setValue : @ ( nativeError . code ) forKey : @ "nativeErrorCode" ] ;
[ errorMap setValue : [ nativeError localizedDescription ] forKey : @ "nativeErrorMessage" ] ;
2017-08-05 20:43:53 +00:00
2017-08-02 15:51:00 +00:00
NSString * code ;
NSString * message ;
NSString * service = @ "Database" ;
2017-08-05 20:43:53 +00:00
2017-08-02 15:51:00 +00:00
switch ( nativeError . code ) {
// iOS confirmed codes
case 1 : // -3 on Android
code = [ RNFirebaseDatabase getCodeWithService : service code : @ "permission-denied" ] ;
message = [ RNFirebaseDatabase getMessageWithService : @ "Client doesn't have permission to access the desired data." service : service fullCode : code ] ;
break ;
case 2 : // -10 on Android
code = [ RNFirebaseDatabase getCodeWithService : service code : @ "unavailable" ] ;
message = [ RNFirebaseDatabase getMessageWithService : @ "The service is unavailable." service : service fullCode : code ] ;
break ;
case 3 : // -25 on Android
code = [ RNFirebaseDatabase getCodeWithService : service code : @ "write-cancelled" ] ;
message = [ RNFirebaseDatabase getMessageWithService : @ "The write was canceled by the user." service : service fullCode : code ] ;
break ;
2017-08-14 10:05:49 +00:00
// TODO : Missing iOS equivalent codes
2017-08-02 15:51:00 +00:00
case -1 :
code = [ RNFirebaseDatabase getCodeWithService : service code : @ "data-stale" ] ;
message = [ RNFirebaseDatabase getMessageWithService : @ "The transaction needs to be run again with current data." service : service fullCode : code ] ;
break ;
case -2 :
code = [ RNFirebaseDatabase getCodeWithService : service code : @ "failure" ] ;
message = [ RNFirebaseDatabase getMessageWithService : @ "The server indicated that this operation failed." service : service fullCode : code ] ;
break ;
case -4 :
code = [ RNFirebaseDatabase getCodeWithService : service code : @ "disconnected" ] ;
message = [ RNFirebaseDatabase getMessageWithService : @ "The operation had to be aborted due to a network disconnect." service : service fullCode : code ] ;
break ;
case -6 :
code = [ RNFirebaseDatabase getCodeWithService : service code : @ "expired-token" ] ;
message = [ RNFirebaseDatabase getMessageWithService : @ "The supplied auth token has expired." service : service fullCode : code ] ;
break ;
case -7 :
code = [ RNFirebaseDatabase getCodeWithService : service code : @ "invalid-token" ] ;
message = [ RNFirebaseDatabase getMessageWithService : @ "The supplied auth token was invalid." service : service fullCode : code ] ;
break ;
case -8 :
code = [ RNFirebaseDatabase getCodeWithService : service code : @ "max-retries" ] ;
message = [ RNFirebaseDatabase getMessageWithService : @ "The transaction had too many retries." service : service fullCode : code ] ;
break ;
case -9 :
code = [ RNFirebaseDatabase getCodeWithService : service code : @ "overridden-by-set" ] ;
message = [ RNFirebaseDatabase getMessageWithService : @ "The transaction was overridden by a subsequent set." service : service fullCode : code ] ;
break ;
case -11 :
code = [ RNFirebaseDatabase getCodeWithService : service code : @ "user-code-exception" ] ;
message = [ RNFirebaseDatabase getMessageWithService : @ "User code called from the Firebase Database runloop threw an exception." service : service fullCode : code ] ;
break ;
case -24 :
code = [ RNFirebaseDatabase getCodeWithService : service code : @ "network-error" ] ;
message = [ RNFirebaseDatabase getMessageWithService : @ "The operation could not be performed due to a network error." service : service fullCode : code ] ;
break ;
default :
code = [ RNFirebaseDatabase getCodeWithService : service code : @ "unknown" ] ;
message = [ RNFirebaseDatabase getMessageWithService : @ "An unknown error occurred." service : service fullCode : code ] ;
break ;
}
2017-08-05 20:43:53 +00:00
2017-08-02 15:51:00 +00:00
[ errorMap setValue : code forKey : @ "code" ] ;
[ errorMap setValue : message forKey : @ "message" ] ;
2017-08-05 20:43:53 +00:00
2017-08-02 15:51:00 +00:00
return errorMap ;
}
2017-08-14 10:05:49 +00:00
- ( NSDictionary * ) createTransactionUpdateMap : ( NSString * ) appName transactionId : ( NSNumber * ) transactionId updatesData : ( FIRMutableData * ) updatesData {
2017-08-02 15:51:00 +00:00
NSMutableDictionary * updatesMap = [ [ NSMutableDictionary alloc ] init ] ;
[ updatesMap setValue : transactionId forKey : @ "id" ] ;
[ updatesMap setValue : @ "update" forKey : @ "type" ] ;
[ updatesMap setValue : appName forKey : @ "appName" ] ;
[ updatesMap setValue : updatesData . value forKey : @ "value" ] ;
2017-08-05 20:43:53 +00:00
2017-08-02 15:51:00 +00:00
return updatesMap ;
}
2017-08-14 10:05:49 +00:00
- ( NSDictionary * ) createTransactionResultMap : ( NSString * ) appName transactionId : ( NSNumber * ) transactionId error : ( NSError * ) error committed : ( BOOL ) committed snapshot : ( FIRDataSnapshot * ) snapshot {
2017-08-02 15:51:00 +00:00
NSMutableDictionary * resultMap = [ [ NSMutableDictionary alloc ] init ] ;
[ resultMap setValue : transactionId forKey : @ "id" ] ;
[ resultMap setValue : appName forKey : @ "appName" ] ;
// TODO : no timeout on iOS
[ resultMap setValue : @ ( committed ) forKey : @ "committed" ] ;
// TODO : no interrupted on iOS
if ( error ! = nil ) {
[ resultMap setValue : @ "error" forKey : @ "type" ] ;
[ resultMap setValue : [ RNFirebaseDatabase getJSError : error ] forKey : @ "error" ] ;
// TODO : timeout error on iOS
} else {
[ resultMap setValue : @ "complete" forKey : @ "type" ] ;
[ resultMap setValue : [ RNFirebaseDatabaseReference snapshotToDict : snapshot ] forKey : @ "snapshot" ] ;
}
2017-08-05 20:43:53 +00:00
2017-08-02 15:51:00 +00:00
return resultMap ;
}
2017-08-14 10:05:49 +00:00
RCT_EXPORT _METHOD ( on : ( NSString * ) appName args : ( NSDictionary * ) args ) {
// todo
// RNFirebaseDatabaseReference * ref = [ self getInternalReferenceForApp : appName refId : refId path : path modifiers : modifiers keep : false ] ;
// TODO query identifier
// [ ref addEventHandler : listenerId eventName : eventName ] ;
2017-05-25 15:00:12 +00:00
}
2017-08-14 10:05:49 +00:00
/ * TODO
2017-05-25 15:00:12 +00:00
RCT_EXPORT _METHOD ( off :
( nonnull
NSNumber * ) refId
listeners : ( NSArray * ) listeners
callback : ( RCTResponseSenderBlock ) callback ) {
2017-07-19 15:02:26 +00:00
RNFirebaseDatabaseReference * ref = _dbReferences [ refId ] ;
2017-04-26 16:34:16 +00:00
if ( ref ! = nil ) {
for ( NSDictionary * listener in listeners ) {
NSNumber * listenerId = [ listener valueForKey : @ "listenerId" ] ;
NSString * eventName = [ listener valueForKey : @ "eventName" ] ;
[ ref removeEventHandler : listenerId eventName : eventName ] ;
2017-03-09 15:26:28 +00:00
if ( ! [ ref hasListeners ] ) {
2017-04-26 16:34:16 +00:00
[ _dbReferences removeObjectForKey : refId ] ;
2017-03-09 15:26:28 +00:00
}
}
}
2017-05-25 15:00:12 +00:00
callback ( @ [ [ NSNull null ] , @ { @ "status" : @ "success" , @ "refId" : refId , } ] ) ;
2017-03-09 15:26:28 +00:00
}
2017-07-19 15:02:26 +00:00
- ( RNFirebaseDatabaseReference * ) getDBHandle : ( NSNumber * ) refId path : ( NSString * ) path modifiers : ( NSArray * ) modifiers {
RNFirebaseDatabaseReference * ref = _dbReferences [ refId ] ;
2017-04-26 16:34:16 +00:00
2017-03-09 15:26:28 +00:00
if ( ref = = nil ) {
2017-07-19 15:02:26 +00:00
ref = [ [ RNFirebaseDatabaseReference alloc ] initWithPathAndModifiers : self database : [ FIRDatabase database ] refId : refId path : path modifiers : modifiers ] ;
2017-05-25 15:00:12 +00:00
_dbReferences [ refId ] = ref ;
2017-03-09 15:26:28 +00:00
}
return ref ;
2017-08-02 15:51:00 +00:00
} * /
2017-03-09 15:26:28 +00:00
2017-08-14 10:05:49 +00:00
2017-03-09 15:26:28 +00:00
- ( NSArray < NSString * > * ) supportedEvents {
2017-08-14 10:05:49 +00:00
return @ [ DATABASE_ON _EVENT , DATABASE_CANCEL _EVENT , DATABASE_TRANSACTION _EVENT ] ;
2017-03-09 15:26:28 +00:00
}
2017-05-25 15:00:12 +00:00
@ end
2017-03-09 15:26:28 +00:00
2017-05-25 15:00:12 +00:00
# else
@ implementation RNFirebaseDatabase
2017-03-09 15:26:28 +00:00
@ end
2017-05-25 15:00:12 +00:00
# endif