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-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-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-02 15:51:00 +00:00
RCT_EXPORT _METHOD ( goOnline : ( NSString * ) appName ) {
[ [ RNFirebaseDatabase getDatabaseForApp : appName ] goOnline ] ;
2017-03-25 00:59:27 +00:00
}
2017-08-02 15:51:00 +00:00
RCT_EXPORT _METHOD ( goOffline : ( NSString * ) appName ) {
[ [ RNFirebaseDatabase getDatabaseForApp : appName ] goOffline ] ;
}
2017-04-26 16:34:16 +00:00
2017-08-02 15:51:00 +00:00
RCT_EXPORT _METHOD ( setPersistence : ( NSString * ) appName
state : ( BOOL ) state ) {
[ RNFirebaseDatabase getDatabaseForApp : appName ] . persistenceEnabled = state ;
2017-03-25 00:59:27 +00:00
}
2017-08-02 15:51:00 +00:00
RCT_EXPORT _METHOD ( keepSynced : ( NSString * ) appName
path : ( NSString * ) path
state : ( BOOL ) state ) {
[ [ self getReferenceForAppPath : appName path : path ] keepSynced : state ] ;
}
2017-04-26 16:34:16 +00:00
2017-08-02 15:51:00 +00:00
RCT_EXPORT _METHOD ( transactionTryCommit : ( NSString * ) appName
transactionId : ( nonnull NSNumber * ) transactionId
updates : ( NSDictionary * ) updates ) {
__block NSMutableDictionary * transactionState ;
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-02 15:51:00 +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-02 15:51:00 +00:00
2017-03-25 00:59:27 +00:00
dispatch_semaphore _t sema = [ transactionState valueForKey : @ "semaphore" ] ;
2017-08-02 15:51:00 +00:00
BOOL abort = [ [ updates valueForKey : @ "abort" ] boolValue ] ;
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-02 15:51:00 +00:00
2017-03-25 00:59:27 +00:00
dispatch_semaphore _signal ( sema ) ;
}
2017-08-02 15:51:00 +00:00
RCT_EXPORT _METHOD ( transactionStart : ( NSString * ) appName
path : ( NSString * ) path
transactionId : ( nonnull NSNumber * ) transactionId
applyLocally : ( BOOL ) applyLocally ) {
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 ] ;
[ ref runTransactionBlock : ^ FIRTransactionResult * _Nonnull ( FIRMutableData *
_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 ] ;
}
2017-05-09 16:20:06 +00:00
}
2017-08-02 15:51:00 +00:00
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 ] ;
}
withLocalEvents :
applyLocally ] ;
} ) ;
}
RCT_EXPORT _METHOD ( onDisconnectSet : ( NSString * ) appName
path : ( NSString * ) path
props : ( NSDictionary * ) props
resolver : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject ) {
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 ] ;
} ] ;
}
RCT_EXPORT _METHOD ( onDisconnectUpdate : ( NSString * ) appName
path : ( NSString * ) path
props : ( NSDictionary * ) props
resolver : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject ) {
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appName path : path ] ;
[ ref onDisconnectUpdateChildValues : props withCompletionBlock : ^ ( NSError * _Nullable error , FIRDatabaseReference * _Nonnull _ref ) {
[ RNFirebaseDatabase handlePromise : resolve rejecter : reject databaseError : error ] ;
} ] ;
}
RCT_EXPORT _METHOD ( onDisconnectRemove : ( NSString * ) appName
path : ( NSString * ) path
resolver : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject ) {
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-02 15:51:00 +00:00
RCT_EXPORT _METHOD ( onDisconnectCancel : ( NSString * ) appName
path : ( NSString * ) path
resolver : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject ) {
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-02 15:51:00 +00:00
RCT_EXPORT _METHOD ( set : ( NSString * ) appName
path : ( NSString * ) path
props : ( NSDictionary * ) props
resolver : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject ) {
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-02 15:51:00 +00:00
RCT_EXPORT _METHOD ( setPriority : ( NSString * ) appName
path : ( NSString * ) path
priority : ( NSDictionary * ) priority
resolver : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject ) {
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appName path : path ] ;
[ ref setPriority : [ priority valueForKey : @ "value" ] withCompletionBlock : ^ ( NSError * _Nullable error , FIRDatabaseReference * _Nonnull ref ) {
[ RNFirebaseDatabase handlePromise : resolve rejecter : reject databaseError : error ] ;
2017-07-19 17:18:16 +00:00
} ] ;
}
2017-08-02 15:51:00 +00:00
RCT_EXPORT _METHOD ( setWithPriority : ( NSString * ) appName
path : ( NSString * ) path
data : ( NSDictionary * ) data
priority : ( NSDictionary * ) priority
resolver : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject ) {
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appName path : path ] ;
[ ref setValue : [ data valueForKey : @ "value" ] andPriority : [ priority valueForKey : @ "value" ] withCompletionBlock : ^ ( NSError * _Nullable error , FIRDatabaseReference * _Nonnull ref ) {
[ RNFirebaseDatabase handlePromise : resolve rejecter : reject databaseError : error ] ;
2017-07-19 17:18:16 +00:00
} ] ;
}
2017-08-02 15:51:00 +00:00
RCT_EXPORT _METHOD ( update : ( NSString * ) appName
path : ( NSString * ) path
props : ( NSDictionary * ) props
resolver : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject ) {
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-02 15:51:00 +00:00
RCT_EXPORT _METHOD ( remove : ( NSString * ) appName
path : ( NSString * ) path
resolver : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject ) {
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-02 15:51:00 +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 ) {
RNFirebaseDatabaseReference * ref = [ self getInternalReferenceForApp : appName refId : refId path : path modifiers : modifiers keep : false ] ;
[ ref addSingleEventHandler : eventName resolver : resolve rejecter : reject ] ;
}
/ *
* INTERNALS / UTILS
* /
+ ( void ) handlePromise : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject
databaseError : ( NSError * ) databaseError {
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-02 15:51:00 +00:00
+ ( FIRDatabase * ) getDatabaseForApp : ( NSString * ) appName {
FIRApp * app = [ FIRApp appNamed : appName ] ;
return [ FIRDatabase databaseForApp : app ] ;
}
- ( FIRDatabaseReference * ) getReferenceForAppPath : ( NSString * ) appName
path : ( NSString * ) path {
return [ [ RNFirebaseDatabase getDatabaseForApp : appName ] referenceWithPath : path ] ;
}
2017-03-09 15:26:28 +00:00
2017-08-02 15:51:00 +00:00
- ( RNFirebaseDatabaseReference * ) getInternalReferenceForApp : ( NSString * ) appName
refId : ( NSNumber * ) refId
path : ( NSString * ) path
modifiers : ( NSArray * ) modifiers
keep : ( BOOL ) keep {
RNFirebaseDatabaseReference * ref = _dbReferences [ refId ] ;
if ( ref = = nil ) {
ref = [ [ RNFirebaseDatabaseReference alloc ] initWithPathAndModifiers : self app : appName refId : refId refPath : path modifiers : modifiers ] ;
if ( keep ) {
_dbReferences [ refId ] = ref ;
}
}
return ref ;
}
// TODO : Move to error util for use in other modules
+ ( NSString * ) getMessageWithService : ( NSString * ) message
service : ( NSString * ) service
fullCode : ( NSString * ) fullCode {
return [ NSString stringWithFormat : @ "%@: %@ (%@)." , service , message , [ fullCode lowercaseString ] ] ;
}
+ ( NSString * ) getCodeWithService : ( NSString * ) service
code : ( NSString * ) code {
return [ NSString stringWithFormat : @ "%@/%@" , [ service uppercaseString ] , [ code uppercaseString ] ] ;
}
+ ( NSDictionary * ) getJSError : ( NSError * ) nativeError {
NSMutableDictionary * errorMap = [ [ NSMutableDictionary alloc ] init ] ;
[ errorMap setValue : @ ( nativeError . code ) forKey : @ "nativeErrorCode" ] ;
[ errorMap setValue : [ nativeError localizedDescription ] forKey : @ "nativeErrorMessage" ] ;
NSString * code ;
NSString * message ;
NSString * service = @ "Database" ;
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 ;
// TODO : Missing iOS equivalent codes
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 ;
}
[ errorMap setValue : code forKey : @ "code" ] ;
[ errorMap setValue : message forKey : @ "message" ] ;
return errorMap ;
}
- ( NSDictionary * ) createTransactionUpdateMap : ( NSString * ) appName
transactionId : ( NSNumber * ) transactionId
updatesData : ( FIRMutableData * ) updatesData {
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" ] ;
return updatesMap ;
}
- ( NSDictionary * ) createTransactionResultMap : ( NSString * ) appName
transactionId : ( NSNumber * ) transactionId
error : ( NSError * ) error
committed : ( BOOL ) committed
snapshot : ( FIRDataSnapshot * ) snapshot {
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" ] ;
}
return resultMap ;
}
/ * TODO
2017-05-25 15:00:12 +00:00
RCT_EXPORT _METHOD ( on :
( nonnull
NSNumber * ) refId
path : ( NSString * ) path
modifiers : ( NSArray * ) modifiers
listenerId : ( nonnull NSNumber * ) listenerId
name : ( NSString * ) eventName
callback : ( RCTResponseSenderBlock ) callback ) {
2017-07-19 15:02:26 +00:00
RNFirebaseDatabaseReference * ref = [ self getDBHandle : refId path : path modifiers : modifiers ] ;
2017-04-26 16:34:16 +00:00
[ ref addEventHandler : listenerId eventName : eventName ] ;
2017-05-25 15:00:12 +00:00
callback ( @ [ [ NSNull null ] , @ { @ "status" : @ "success" , @ "refId" : refId , @ "handle" : path } ] ) ;
}
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
// Not sure how to get away from this . . . yet
- ( NSArray < NSString * > * ) supportedEvents {
2017-03-25 00:59:27 +00:00
return @ [ DATABASE_DATA _EVENT , DATABASE_ERROR _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