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-08-17 16:32:09 +00:00
# import < Firebase . h >
2017-07-19 15:02:26 +00:00
# import "RNFirebaseDatabaseReference.h"
# import "RNFirebaseEvents.h"
2017-10-26 10:55:07 +00:00
# import "RNFirebaseUtil.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
2018-05-15 09:02:18 +00:00
// Run on a different thread
- ( dispatch_queue _t ) methodQueue {
return dispatch_queue _create ( "io.invertase.react-native-firebase.database" , DISPATCH_QUEUE _SERIAL ) ;
}
2017-08-14 10:05:49 +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 ] ;
2018-05-15 09:02:18 +00:00
_transactionQueue = dispatch_queue _create ( "io.invertase.react-native-firebase.database.transactions" , DISPATCH_QUEUE _CONCURRENT ) ;
2017-03-09 15:26:28 +00:00
}
return self ;
}
2017-11-21 23:37:05 +00:00
RCT_EXPORT _METHOD ( goOnline : ( NSString * ) appDisplayName
dbURL : ( NSString * ) dbURL ) {
[ [ RNFirebaseDatabase getDatabaseForApp : appDisplayName URL : dbURL ] goOnline ] ;
2017-03-25 00:59:27 +00:00
}
2017-11-21 23:37:05 +00:00
RCT_EXPORT _METHOD ( goOffline : ( NSString * ) appDisplayName
dbURL : ( NSString * ) dbURL ) {
[ [ RNFirebaseDatabase getDatabaseForApp : appDisplayName URL : dbURL ] goOffline ] ;
2017-08-02 15:51:00 +00:00
}
2017-04-26 16:34:16 +00:00
2018-03-04 23:45:37 +00:00
RCT_EXPORT _METHOD ( setPersistence : ( NSString * ) appDisplayName
2017-11-21 23:37:05 +00:00
dbURL : ( NSString * ) dbURL
2018-03-04 23:45:37 +00:00
state : ( BOOL ) state ) {
2017-11-21 23:37:05 +00:00
[ RNFirebaseDatabase getDatabaseForApp : appDisplayName URL : dbURL ] . persistenceEnabled = state ;
2017-03-25 00:59:27 +00:00
}
2018-03-04 23:45:37 +00:00
RCT_EXPORT _METHOD ( setPersistenceCacheSizeBytes : ( NSString * ) appDisplayName
2017-11-21 23:37:05 +00:00
dbURL : ( NSString * ) dbURL
2018-03-04 23:45:37 +00:00
size : ( NSInteger * ) size ) {
2017-11-21 23:37:05 +00:00
[ RNFirebaseDatabase getDatabaseForApp : appDisplayName URL : dbURL ] . persistenceCacheSizeBytes = ( NSUInteger ) size ;
2017-11-08 11:32:18 +00:00
}
2018-03-04 23:45:37 +00:00
RCT_EXPORT _METHOD ( enableLogging : ( BOOL ) enabled ) {
2017-11-08 11:15:24 +00:00
[ FIRDatabase setLoggingEnabled : enabled ] ;
}
2018-03-04 23:45:37 +00:00
RCT_EXPORT _METHOD ( keepSynced : ( NSString * ) appDisplayName
2017-11-21 23:37:05 +00:00
dbURL : ( NSString * ) dbURL
2018-03-04 23:45:37 +00:00
key : ( NSString * ) key
path : ( NSString * ) path
modifiers : ( NSArray * ) modifiers
state : ( BOOL ) state ) {
2017-11-21 23:37:05 +00:00
FIRDatabaseQuery * query = [ self getInternalReferenceForApp : appDisplayName dbURL : dbURL key : key path : path modifiers : modifiers ] . 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
2018-03-04 23:45:37 +00:00
RCT_EXPORT _METHOD ( transactionTryCommit : ( NSString * ) appDisplayName
2017-11-21 23:37:05 +00:00
dbURL : ( NSString * ) dbURL
2018-03-04 23:45:37 +00:00
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 , ^ {
2018-03-04 23:45:37 +00:00
transactionState = _transactions [ [ transactionId stringValue ] ] ;
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
2018-03-04 23:45:37 +00:00
RCT_EXPORT _METHOD ( transactionStart : ( NSString * ) appDisplayName
2017-11-21 23:37:05 +00:00
dbURL : ( NSString * ) dbURL
2018-03-04 23:45:37 +00:00
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 ;
2017-11-21 23:37:05 +00:00
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appDisplayName dbURL : dbURL path : path ] ;
2017-08-05 20:43:53 +00:00
2018-03-04 23:45:37 +00:00
[ ref runTransactionBlock : ^ FIRTransactionResult * _Nonnull ( FIRMutableData * _Nonnull currentData ) {
dispatch_barrier _async ( _transactionQueue , ^ {
[ _transactions setValue : transactionState forKey : [ transactionId stringValue ] ] ;
2017-11-21 23:37:05 +00:00
NSDictionary * updateMap = [ self createTransactionUpdateMap : appDisplayName dbURL : dbURL transactionId : transactionId updatesData : currentData ] ;
2018-03-04 23:45:37 +00:00
[ RNFirebaseUtil sendJSEvent : self name : 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 stringValue ] ] ;
} ) ;
if ( abort ) {
return [ FIRTransactionResult abort ] ;
} else {
currentData . value = value ;
return [ FIRTransactionResult successWithValue : currentData ] ;
}
} andCompletionBlock : ^ ( NSError * _Nullable databaseError , BOOL committed , FIRDataSnapshot * _Nullable snapshot ) {
2017-11-21 23:37:05 +00:00
NSDictionary * resultMap = [ self createTransactionResultMap : appDisplayName dbURL : dbURL transactionId : transactionId error : databaseError committed : committed snapshot : snapshot ] ;
2017-10-26 10:55:07 +00:00
[ RNFirebaseUtil sendJSEvent : self name : DATABASE_TRANSACTION _EVENT body : resultMap ] ;
2018-03-04 23:45:37 +00:00
} withLocalEvents : applyLocally ] ;
2017-08-02 15:51:00 +00:00
} ) ;
}
2018-03-04 23:45:37 +00:00
RCT_EXPORT _METHOD ( onDisconnectSet : ( NSString * ) appDisplayName
2017-11-21 23:37:05 +00:00
dbURL : ( NSString * ) dbURL
2018-03-04 23:45:37 +00:00
path : ( NSString * ) path
props : ( NSDictionary * ) props
resolver : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject ) {
2017-11-21 23:37:05 +00:00
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appDisplayName dbURL : dbURL path : path ] ;
2017-08-02 15:51:00 +00:00
[ ref onDisconnectSetValue : props [ @ "value" ] withCompletionBlock : ^ ( NSError * _Nullable error , FIRDatabaseReference * _Nonnull _ref ) {
[ RNFirebaseDatabase handlePromise : resolve rejecter : reject databaseError : error ] ;
} ] ;
}
2018-03-04 23:45:37 +00:00
RCT_EXPORT _METHOD ( onDisconnectUpdate : ( NSString * ) appDisplayName
2017-11-21 23:37:05 +00:00
dbURL : ( NSString * ) dbURL
2018-03-04 23:45:37 +00:00
path : ( NSString * ) path
props : ( NSDictionary * ) props
resolver : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject ) {
2017-11-21 23:37:05 +00:00
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appDisplayName dbURL : dbURL path : path ] ;
2017-08-02 15:51:00 +00:00
[ ref onDisconnectUpdateChildValues : props withCompletionBlock : ^ ( NSError * _Nullable error , FIRDatabaseReference * _Nonnull _ref ) {
[ RNFirebaseDatabase handlePromise : resolve rejecter : reject databaseError : error ] ;
} ] ;
}
2018-03-04 23:45:37 +00:00
RCT_EXPORT _METHOD ( onDisconnectRemove : ( NSString * ) appDisplayName
2017-11-21 23:37:05 +00:00
dbURL : ( NSString * ) dbURL
2018-03-04 23:45:37 +00:00
path : ( NSString * ) path
resolver : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject ) {
2017-11-21 23:37:05 +00:00
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appDisplayName dbURL : dbURL path : path ] ;
2017-08-02 15:51:00 +00:00
[ ref onDisconnectRemoveValueWithCompletionBlock : ^ ( NSError * _Nullable error , FIRDatabaseReference * _Nonnull _ref ) {
[ RNFirebaseDatabase handlePromise : resolve rejecter : reject databaseError : error ] ;
} ] ;
2017-03-09 15:26:28 +00:00
}
2018-03-04 23:45:37 +00:00
RCT_EXPORT _METHOD ( onDisconnectCancel : ( NSString * ) appDisplayName
2017-11-21 23:37:05 +00:00
dbURL : ( NSString * ) dbURL
2018-03-04 23:45:37 +00:00
path : ( NSString * ) path
resolver : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject ) {
2017-11-21 23:37:05 +00:00
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appDisplayName dbURL : dbURL path : path ] ;
2017-08-02 15:51:00 +00:00
[ ref cancelDisconnectOperationsWithCompletionBlock : ^ ( NSError * _Nullable error , FIRDatabaseReference * _Nonnull _ref ) {
[ RNFirebaseDatabase handlePromise : resolve rejecter : reject databaseError : error ] ;
} ] ;
2017-03-09 15:26:28 +00:00
}
2018-03-04 23:45:37 +00:00
RCT_EXPORT _METHOD ( set : ( NSString * ) appDisplayName
2017-11-21 23:37:05 +00:00
dbURL : ( NSString * ) dbURL
2018-03-04 23:45:37 +00:00
path : ( NSString * ) path
props : ( NSDictionary * ) props
resolver : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject ) {
2017-11-21 23:37:05 +00:00
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appDisplayName dbURL : dbURL path : path ] ;
2017-08-02 15:51:00 +00:00
[ 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
} ] ;
}
2018-03-04 23:45:37 +00:00
RCT_EXPORT _METHOD ( setPriority : ( NSString * ) appDisplayName
2017-11-21 23:37:05 +00:00
dbURL : ( NSString * ) dbURL
2018-03-04 23:45:37 +00:00
path : ( NSString * ) path
priority : ( NSDictionary * ) priority
resolver : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject ) {
2017-11-21 23:37:05 +00:00
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appDisplayName dbURL : dbURL 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
} ] ;
}
2018-03-04 23:45:37 +00:00
RCT_EXPORT _METHOD ( setWithPriority : ( NSString * ) appDisplayName
2017-11-21 23:37:05 +00:00
dbURL : ( NSString * ) dbURL
2018-03-04 23:45:37 +00:00
path : ( NSString * ) path
data : ( NSDictionary * ) data
priority : ( NSDictionary * ) priority
resolver : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject ) {
2017-11-21 23:37:05 +00:00
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appDisplayName dbURL : dbURL 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
} ] ;
}
2018-03-04 23:45:37 +00:00
RCT_EXPORT _METHOD ( update : ( NSString * ) appDisplayName
2017-11-21 23:37:05 +00:00
dbURL : ( NSString * ) dbURL
2018-03-04 23:45:37 +00:00
path : ( NSString * ) path
props : ( NSDictionary * ) props
resolver : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject ) {
2017-11-21 23:37:05 +00:00
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appDisplayName dbURL : dbURL path : path ] ;
2017-08-02 15:51:00 +00:00
[ 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
} ] ;
}
2018-03-04 23:45:37 +00:00
RCT_EXPORT _METHOD ( remove : ( NSString * ) appDisplayName
2017-11-21 23:37:05 +00:00
dbURL : ( NSString * ) dbURL
2018-03-04 23:45:37 +00:00
path : ( NSString * ) path
resolver : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject ) {
2017-11-21 23:37:05 +00:00
FIRDatabaseReference * ref = [ self getReferenceForAppPath : appDisplayName dbURL : dbURL 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
} ] ;
}
2018-03-04 23:45:37 +00:00
RCT_EXPORT _METHOD ( once : ( NSString * ) appDisplayName
2017-11-21 23:37:05 +00:00
dbURL : ( NSString * ) dbURL
2018-03-04 23:45:37 +00:00
key : ( NSString * ) key
path : ( NSString * ) path
modifiers : ( NSArray * ) modifiers
eventName : ( NSString * ) eventName
resolver : ( RCTPromiseResolveBlock ) resolve
rejecter : ( RCTPromiseRejectBlock ) reject ) {
2017-11-21 23:37:05 +00:00
RNFirebaseDatabaseReference * ref = [ self getInternalReferenceForApp : appDisplayName dbURL : dbURL key : key path : path modifiers : modifiers ] ;
2017-08-22 16:29:02 +00:00
[ ref once : eventName resolver : resolve rejecter : reject ] ;
}
2018-03-04 23:45:37 +00:00
RCT_EXPORT _METHOD ( on : ( NSString * ) appDisplayName
2017-11-21 23:37:05 +00:00
dbURL : ( NSString * ) dbURL
2018-03-04 23:45:37 +00:00
props : ( NSDictionary * ) props ) {
2017-11-21 23:37:05 +00:00
RNFirebaseDatabaseReference * ref = [ self getCachedInternalReferenceForApp : appDisplayName dbURL : dbURL props : props ] ;
2017-08-22 16:29:02 +00:00
[ ref on : props [ @ "eventType" ] registration : props [ @ "registration" ] ] ;
}
2018-03-04 23:45:37 +00:00
RCT_EXPORT _METHOD ( off : ( NSString * ) key
eventRegistrationKey : ( NSString * ) eventRegistrationKey ) {
2017-08-22 16:29:02 +00:00
RNFirebaseDatabaseReference * ref = _dbReferences [ key ] ;
2017-10-18 09:29:11 +00:00
if ( ref ) {
[ ref removeEventListener : eventRegistrationKey ] ;
2017-08-28 12:53:09 +00:00
2017-10-18 09:29:11 +00:00
if ( ! [ ref hasListeners ] ) {
[ _dbReferences removeObjectForKey : key ] ;
}
2017-08-22 16:29:02 +00:00
}
2017-08-02 15:51:00 +00:00
}
2017-08-22 16:29:02 +00:00
2017-08-02 15:51:00 +00:00
/ *
* 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
}
}
2018-01-03 20:00:38 +00:00
+ ( FIRDatabase * ) getDatabaseForApp : ( NSString * ) appDisplayName {
FIRApp * app = [ RNFirebaseUtil getApp : appDisplayName ] ;
2017-08-02 15:51:00 +00:00
return [ FIRDatabase databaseForApp : app ] ;
}
2017-11-21 23:37:05 +00:00
+ ( FIRDatabase * ) getDatabaseForApp : ( NSString * ) appDisplayName URL : ( NSString * ) url {
if ( url = = nil ) {
return [ self getDatabaseForApp : appDisplayName ] ;
}
FIRApp * app = [ RNFirebaseUtil getApp : appDisplayName ] ;
return [ FIRDatabase databaseForApp : app URL : url ] ;
}
- ( FIRDatabaseReference * ) getReferenceForAppPath : ( NSString * ) appDisplayName dbURL : ( NSString * ) dbURL path : ( NSString * ) path {
return [ [ RNFirebaseDatabase getDatabaseForApp : appDisplayName URL : dbURL ] referenceWithPath : path ] ;
2017-08-02 15:51:00 +00:00
}
2017-03-09 15:26:28 +00:00
2017-11-21 23:37:05 +00:00
- ( RNFirebaseDatabaseReference * ) getInternalReferenceForApp : ( NSString * ) appDisplayName dbURL : ( NSString * ) dbURL key : ( NSString * ) key path : ( NSString * ) path modifiers : ( NSArray * ) modifiers {
return [ [ RNFirebaseDatabaseReference alloc ] initWithPathAndModifiers : self appDisplayName : appDisplayName dbURL : dbURL key : key refPath : path modifiers : modifiers ] ;
2017-10-23 16:03:49 +00:00
}
2017-08-05 20:43:53 +00:00
2017-11-21 23:37:05 +00:00
- ( RNFirebaseDatabaseReference * ) getCachedInternalReferenceForApp : ( NSString * ) appDisplayName dbURL : ( NSString * ) dbURL props : ( NSDictionary * ) props {
2017-10-23 16:03:49 +00:00
NSString * key = props [ @ "key" ] ;
NSString * path = props [ @ "path" ] ;
2017-11-21 23:37:05 +00:00
NSArray * modifiers = props [ @ "modifiers" ] ;
2017-10-26 10:55:07 +00:00
2017-10-23 16:03:49 +00:00
RNFirebaseDatabaseReference * ref = _dbReferences [ key ] ;
2017-10-26 10:55:07 +00:00
2017-08-02 15:51:00 +00:00
if ( ref = = nil ) {
2017-11-21 23:37:05 +00:00
ref = [ [ RNFirebaseDatabaseReference alloc ] initWithPathAndModifiers : self appDisplayName : appDisplayName dbURL : dbURL key : key refPath : path modifiers : modifiers ] ;
2017-10-23 16:03:49 +00:00
_dbReferences [ key ] = ref ;
2017-08-02 15:51:00 +00:00
}
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-28 12:53:09 +00:00
return [ NSString stringWithFormat : @ "%@/%@" , [ service lowercaseString ] , [ code lowercaseString ] ] ;
2017-08-02 15:51:00 +00:00
}
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 ;
2018-03-04 23:45:37 +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-11-21 23:37:05 +00:00
- ( NSDictionary * ) createTransactionUpdateMap : ( NSString * ) appDisplayName dbURL : ( NSString * ) dbURL 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" ] ;
2018-01-03 20:00:38 +00:00
[ updatesMap setValue : appDisplayName forKey : @ "appName" ] ;
2017-11-21 23:37:05 +00:00
[ updatesMap setValue : dbURL forKey : @ "dbURL" ] ;
2017-08-02 15:51:00 +00:00
[ 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-11-21 23:37:05 +00:00
- ( NSDictionary * ) createTransactionResultMap : ( NSString * ) appDisplayName dbURL : ( NSString * ) dbURL 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" ] ;
2018-01-03 20:00:38 +00:00
[ resultMap setValue : appDisplayName forKey : @ "appName" ] ;
2017-11-21 23:37:05 +00:00
[ resultMap setValue : dbURL forKey : @ "dbURL" ] ;
2017-08-02 15:51:00 +00:00
// 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-03-09 15:26:28 +00:00
- ( NSArray < NSString * > * ) supportedEvents {
2017-08-16 20:39:05 +00:00
return @ [ DATABASE_SYNC _EVENT , DATABASE_TRANSACTION _EVENT ] ;
2017-03-09 15:26:28 +00:00
}
2018-03-04 23:45:37 +00:00
+ ( BOOL ) requiresMainQueueSetup {
2017-10-12 08:18:01 +00:00
return YES ;
}
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