[database][ios][wip] Replicate Android changes on iOS
This commit is contained in:
parent
3504715a53
commit
a785b050db
@ -74,6 +74,7 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
|
|||||||
*/
|
*/
|
||||||
@ReactMethod
|
@ReactMethod
|
||||||
public void keepSynced(String appName, String path, Boolean state) {
|
public void keepSynced(String appName, String path, Boolean state) {
|
||||||
|
// TODO: Needs to take into account modifiers as well as just the path
|
||||||
getReferenceForAppPath(appName, path).keepSynced(state);
|
getReferenceForAppPath(appName, path).keepSynced(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -579,7 +580,7 @@ public class RNFirebaseDatabase extends ReactContextBaseJavaModule {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
code = getCodeWithService(service, "unknown");
|
code = getCodeWithService(service, "unknown");
|
||||||
message = getMessageWithService("An unknown error occurred", service, code);
|
message = getMessageWithService("An unknown error occurred.", service, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
errorMap.putString("code", code);
|
errorMap.putString("code", code);
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
|
8300A7AE1F31E143001B16AB /* RNFirebaseDatabaseReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 8300A7AD1F31E143001B16AB /* RNFirebaseDatabaseReference.m */; };
|
||||||
839D916C1EF3E20B0077C7C8 /* RNFirebaseAdMob.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D914F1EF3E20A0077C7C8 /* RNFirebaseAdMob.m */; };
|
839D916C1EF3E20B0077C7C8 /* RNFirebaseAdMob.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D914F1EF3E20A0077C7C8 /* RNFirebaseAdMob.m */; };
|
||||||
839D916D1EF3E20B0077C7C8 /* RNFirebaseAdMobInterstitial.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91511EF3E20A0077C7C8 /* RNFirebaseAdMobInterstitial.m */; };
|
839D916D1EF3E20B0077C7C8 /* RNFirebaseAdMobInterstitial.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91511EF3E20A0077C7C8 /* RNFirebaseAdMobInterstitial.m */; };
|
||||||
839D916E1EF3E20B0077C7C8 /* RNFirebaseAdMobRewardedVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91531EF3E20A0077C7C8 /* RNFirebaseAdMobRewardedVideo.m */; };
|
839D916E1EF3E20B0077C7C8 /* RNFirebaseAdMobRewardedVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91531EF3E20A0077C7C8 /* RNFirebaseAdMobRewardedVideo.m */; };
|
||||||
@ -35,6 +36,8 @@
|
|||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
134814201AA4EA6300B7C361 /* libRNFirebase.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNFirebase.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
134814201AA4EA6300B7C361 /* libRNFirebase.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNFirebase.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
8300A7AC1F31E143001B16AB /* RNFirebaseDatabaseReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseDatabaseReference.h; sourceTree = "<group>"; };
|
||||||
|
8300A7AD1F31E143001B16AB /* RNFirebaseDatabaseReference.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseDatabaseReference.m; sourceTree = "<group>"; };
|
||||||
839D914E1EF3E20A0077C7C8 /* RNFirebaseAdMob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseAdMob.h; sourceTree = "<group>"; };
|
839D914E1EF3E20A0077C7C8 /* RNFirebaseAdMob.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseAdMob.h; sourceTree = "<group>"; };
|
||||||
839D914F1EF3E20A0077C7C8 /* RNFirebaseAdMob.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseAdMob.m; sourceTree = "<group>"; };
|
839D914F1EF3E20A0077C7C8 /* RNFirebaseAdMob.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseAdMob.m; sourceTree = "<group>"; };
|
||||||
839D91501EF3E20A0077C7C8 /* RNFirebaseAdMobInterstitial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseAdMobInterstitial.h; sourceTree = "<group>"; };
|
839D91501EF3E20A0077C7C8 /* RNFirebaseAdMobInterstitial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseAdMobInterstitial.h; sourceTree = "<group>"; };
|
||||||
@ -157,6 +160,8 @@
|
|||||||
839D91601EF3E20A0077C7C8 /* database */ = {
|
839D91601EF3E20A0077C7C8 /* database */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
8300A7AC1F31E143001B16AB /* RNFirebaseDatabaseReference.h */,
|
||||||
|
8300A7AD1F31E143001B16AB /* RNFirebaseDatabaseReference.m */,
|
||||||
839D91611EF3E20A0077C7C8 /* RNFirebaseDatabase.h */,
|
839D91611EF3E20A0077C7C8 /* RNFirebaseDatabase.h */,
|
||||||
839D91621EF3E20A0077C7C8 /* RNFirebaseDatabase.m */,
|
839D91621EF3E20A0077C7C8 /* RNFirebaseDatabase.m */,
|
||||||
);
|
);
|
||||||
@ -262,6 +267,7 @@
|
|||||||
839D91741EF3E20B0077C7C8 /* RNFirebaseMessaging.m in Sources */,
|
839D91741EF3E20B0077C7C8 /* RNFirebaseMessaging.m in Sources */,
|
||||||
839D91751EF3E20B0077C7C8 /* RNFirebasePerformance.m in Sources */,
|
839D91751EF3E20B0077C7C8 /* RNFirebasePerformance.m in Sources */,
|
||||||
839D916D1EF3E20B0077C7C8 /* RNFirebaseAdMobInterstitial.m in Sources */,
|
839D916D1EF3E20B0077C7C8 /* RNFirebaseAdMobInterstitial.m in Sources */,
|
||||||
|
8300A7AE1F31E143001B16AB /* RNFirebaseDatabaseReference.m in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
|
@ -4,12 +4,19 @@
|
|||||||
#import <React/RCTBridgeModule.h>
|
#import <React/RCTBridgeModule.h>
|
||||||
|
|
||||||
#if __has_include(<FirebaseDatabase/FIRDatabase.h>)
|
#if __has_include(<FirebaseDatabase/FIRDatabase.h>)
|
||||||
|
#import "Firebase.h"
|
||||||
#import <React/RCTEventEmitter.h>
|
#import <React/RCTEventEmitter.h>
|
||||||
|
|
||||||
@interface RNFirebaseDatabase : RCTEventEmitter<RCTBridgeModule> {}
|
@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;
|
||||||
|
|
||||||
|
+ (void)handlePromise:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock) reject databaseError:(NSError *)databaseError;
|
||||||
|
+ (FIRDatabase *)getDatabaseForApp:(NSString*)appName;
|
||||||
|
+ (NSString *) getMessageWithService:(NSString *) message service:(NSString *) service fullCode:(NSString *) fullCode;
|
||||||
|
+ (NSString *) getCodeWithService:(NSString *) service code:(NSString *) code;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
#if __has_include(<FirebaseDatabase/FIRDatabase.h>)
|
#if __has_include(<FirebaseDatabase/FIRDatabase.h>)
|
||||||
#import "RNFirebaseDatabaseReference.h"
|
#import "RNFirebaseDatabaseReference.h"
|
||||||
#import "RNFirebaseEvents.h"
|
#import "RNFirebaseEvents.h"
|
||||||
#import "Firebase.h"
|
|
||||||
|
|
||||||
@implementation RNFirebaseDatabase
|
@implementation RNFirebaseDatabase
|
||||||
RCT_EXPORT_MODULE();
|
RCT_EXPORT_MODULE();
|
||||||
@ -18,32 +17,70 @@ RCT_EXPORT_MODULE();
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)sendTransactionEvent:(NSString *)type body:(id)body {
|
RCT_EXPORT_METHOD(goOnline:(NSString *) appName) {
|
||||||
@try {
|
[[RNFirebaseDatabase getDatabaseForApp:appName] goOnline];
|
||||||
[self sendEventWithName:type body:body];
|
|
||||||
} @catch (NSException *err) {
|
|
||||||
NSLog(@"An error occurred in sendJSEvent: %@", [err debugDescription]);
|
|
||||||
NSLog(@"Tried to send: %@ with %@", type, body);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(startTransaction:
|
RCT_EXPORT_METHOD(goOffline:(NSString *) appName) {
|
||||||
(NSString *) path
|
[[RNFirebaseDatabase getDatabaseForApp:appName] goOffline];
|
||||||
identifier:
|
}
|
||||||
(NSString *) identifier
|
|
||||||
applyLocally:
|
RCT_EXPORT_METHOD(setPersistence:(NSString *) appName
|
||||||
(BOOL) applyLocally) {
|
state:(BOOL) state) {
|
||||||
|
[RNFirebaseDatabase getDatabaseForApp:appName].persistenceEnabled = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_METHOD(keepSynced:(NSString *) appName
|
||||||
|
path:(NSString *) path
|
||||||
|
state:(BOOL) state) {
|
||||||
|
[[self getReferenceForAppPath:appName path:path] keepSynced:state];
|
||||||
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_METHOD(transactionTryCommit:(NSString *) appName
|
||||||
|
transactionId:(nonnull NSNumber *) transactionId
|
||||||
|
updates:(NSDictionary *) updates) {
|
||||||
|
__block NSMutableDictionary *transactionState;
|
||||||
|
|
||||||
|
dispatch_sync(_transactionQueue, ^{
|
||||||
|
transactionState = _transactions[transactionId];
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!transactionState) {
|
||||||
|
NSLog(@"tryCommitTransaction for unknown ID %@", transactionId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch_semaphore_t sema = [transactionState valueForKey:@"semaphore"];
|
||||||
|
|
||||||
|
BOOL abort = [[updates valueForKey:@"abort"] boolValue];
|
||||||
|
|
||||||
|
if (abort) {
|
||||||
|
[transactionState setValue:@true forKey:@"abort"];
|
||||||
|
} else {
|
||||||
|
id newValue = [updates valueForKey:@"value"];
|
||||||
|
[transactionState setValue:newValue forKey:@"value"];
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatch_semaphore_signal(sema);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RCT_EXPORT_METHOD(transactionStart:(NSString *) appName
|
||||||
|
path:(NSString *) path
|
||||||
|
transactionId:(nonnull NSNumber *) transactionId
|
||||||
|
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[@"semaphore"] = sema;
|
transactionState[@"semaphore"] = sema;
|
||||||
FIRDatabaseReference *ref = [self getPathRef:path];
|
FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path];
|
||||||
|
|
||||||
[ref runTransactionBlock:^FIRTransactionResult * _Nonnull(FIRMutableData *
|
[ref runTransactionBlock:^FIRTransactionResult * _Nonnull(FIRMutableData *
|
||||||
_Nonnull currentData) {
|
_Nonnull currentData) {
|
||||||
dispatch_barrier_async(_transactionQueue, ^{
|
dispatch_barrier_async(_transactionQueue, ^{
|
||||||
[_transactions setValue:transactionState forKey:identifier];
|
[_transactions setValue:transactionState forKey:transactionId];
|
||||||
[self sendTransactionEvent:DATABASE_TRANSACTION_EVENT body:@{@"id": identifier, @"type": @"update", @"value": currentData.value}];
|
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
|
// wait for the js event handler to call tryCommitTransaction
|
||||||
@ -57,7 +94,7 @@ RCT_EXPORT_METHOD(startTransaction:
|
|||||||
id value = [transactionState valueForKey:@"value"];
|
id value = [transactionState valueForKey:@"value"];
|
||||||
|
|
||||||
dispatch_barrier_async(_transactionQueue, ^{
|
dispatch_barrier_async(_transactionQueue, ^{
|
||||||
[_transactions removeObjectForKey:identifier];
|
[_transactions removeObjectForKey:transactionId];
|
||||||
});
|
});
|
||||||
|
|
||||||
if (abort) {
|
if (abort) {
|
||||||
@ -69,155 +106,285 @@ RCT_EXPORT_METHOD(startTransaction:
|
|||||||
}
|
}
|
||||||
andCompletionBlock:
|
andCompletionBlock:
|
||||||
^(NSError *_Nullable databaseError, BOOL committed, FIRDataSnapshot *_Nullable snapshot) {
|
^(NSError *_Nullable databaseError, BOOL committed, FIRDataSnapshot *_Nullable snapshot) {
|
||||||
if (databaseError != nil) {
|
NSDictionary *resultMap = [self createTransactionResultMap:appName transactionId:transactionId error:databaseError committed:committed snapshot:snapshot];
|
||||||
[self sendTransactionEvent:DATABASE_TRANSACTION_EVENT body:@{@"id": identifier, @"type": @"error", @"code": @([databaseError code]), @"message": [databaseError description]}];
|
[self sendEventWithName:DATABASE_TRANSACTION_EVENT body:resultMap];
|
||||||
} else {
|
|
||||||
[self sendTransactionEvent:DATABASE_TRANSACTION_EVENT body:@{@"id": identifier, @"type": @"complete", @"committed": @(committed), @"snapshot": [RNFirebaseDatabaseReference snapshotToDict:snapshot],}];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
withLocalEvents:
|
withLocalEvents:
|
||||||
applyLocally];
|
applyLocally];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(tryCommitTransaction:
|
RCT_EXPORT_METHOD(onDisconnectSet:(NSString *) appName
|
||||||
(NSString *) identifier
|
path:(NSString *) path
|
||||||
withData:
|
props:(NSDictionary *) props
|
||||||
(NSDictionary *) data) {
|
resolver:(RCTPromiseResolveBlock) resolve
|
||||||
__block NSMutableDictionary *transactionState;
|
rejecter:(RCTPromiseRejectBlock) reject) {
|
||||||
|
FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path];
|
||||||
dispatch_sync(_transactionQueue, ^{
|
[ref onDisconnectSetValue:props[@"value"] withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
|
||||||
transactionState = _transactions[identifier];
|
[RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error];
|
||||||
});
|
|
||||||
|
|
||||||
if (!transactionState) {
|
|
||||||
NSLog(@"tryCommitTransaction for unknown ID %@", identifier);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch_semaphore_t sema = [transactionState valueForKey:@"semaphore"];
|
|
||||||
|
|
||||||
BOOL abort = [[data valueForKey:@"abort"] boolValue];
|
|
||||||
|
|
||||||
if (abort) {
|
|
||||||
[transactionState setValue:@true forKey:@"abort"];
|
|
||||||
} else {
|
|
||||||
id newValue = [data valueForKey:@"value"];
|
|
||||||
[transactionState setValue:newValue forKey:@"value"];
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch_semaphore_signal(sema);
|
|
||||||
}
|
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(enablePersistence:
|
|
||||||
(BOOL) enable
|
|
||||||
callback:
|
|
||||||
(RCTResponseSenderBlock) callback) {
|
|
||||||
|
|
||||||
BOOL isEnabled = [FIRDatabase database].persistenceEnabled;
|
|
||||||
if (isEnabled != enable) {
|
|
||||||
@try {
|
|
||||||
[FIRDatabase database].persistenceEnabled = enable;
|
|
||||||
} @catch (NSException *exception) {
|
|
||||||
// do nothing - for RN packager reloads
|
|
||||||
}
|
|
||||||
}
|
|
||||||
callback(@[[NSNull null], @{@"result": @"success"}]);
|
|
||||||
}
|
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(keepSynced:
|
|
||||||
(NSString *) path
|
|
||||||
withEnable:
|
|
||||||
(BOOL) enable
|
|
||||||
callback:
|
|
||||||
(RCTResponseSenderBlock) callback) {
|
|
||||||
FIRDatabaseReference *ref = [self getPathRef:path];
|
|
||||||
[ref keepSynced:enable];
|
|
||||||
callback(@[[NSNull null], @{@"status": @"success", @"path": path}]);
|
|
||||||
}
|
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(set:
|
|
||||||
(NSString *) path
|
|
||||||
data:
|
|
||||||
(NSDictionary *) data
|
|
||||||
callback:
|
|
||||||
(RCTResponseSenderBlock) callback) {
|
|
||||||
FIRDatabaseReference *ref = [self getPathRef:path];
|
|
||||||
[ref setValue:[data valueForKey:@"value"] withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
|
|
||||||
[self handleCallback:@"set" callback:callback databaseError:error];
|
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(priority:(NSString *) path
|
RCT_EXPORT_METHOD(onDisconnectUpdate:(NSString *) appName
|
||||||
priorityData:(NSDictionary *) priorityData
|
path:(NSString *) path
|
||||||
callback:(RCTResponseSenderBlock) callback) {
|
props:(NSDictionary *) props
|
||||||
FIRDatabaseReference *ref = [self getPathRef:path];
|
resolver:(RCTPromiseResolveBlock) resolve
|
||||||
[ref setPriority:[priorityData valueForKey:@"value"] withCompletionBlock:^(NSError * _Nullable error, FIRDatabaseReference * _Nonnull ref) {
|
rejecter:(RCTPromiseRejectBlock) reject) {
|
||||||
[self handleCallback:@"priority" callback:callback databaseError:error];
|
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(withPriority:(NSString *) path
|
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];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
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];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
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];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
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];
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
RCT_EXPORT_METHOD(setWithPriority:(NSString *) appName
|
||||||
|
path:(NSString *) path
|
||||||
data:(NSDictionary *) data
|
data:(NSDictionary *) data
|
||||||
priorityData:(NSDictionary *) priorityData
|
priority:(NSDictionary *) priority
|
||||||
callback:(RCTResponseSenderBlock) callback) {
|
resolver:(RCTPromiseResolveBlock) resolve
|
||||||
FIRDatabaseReference *ref = [self getPathRef:path];
|
rejecter:(RCTPromiseRejectBlock) reject) {
|
||||||
[ref setValue:[data valueForKey:@"value"] andPriority:[priorityData valueForKey:@"value"] withCompletionBlock:^(NSError * _Nullable error, FIRDatabaseReference * _Nonnull ref) {
|
FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path];
|
||||||
[self handleCallback:@"withPriority" callback:callback databaseError:error];
|
[ref setValue:[data valueForKey:@"value"] andPriority:[priority valueForKey:@"value"] withCompletionBlock:^(NSError * _Nullable error, FIRDatabaseReference * _Nonnull ref) {
|
||||||
|
[RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(update:
|
RCT_EXPORT_METHOD(update:(NSString *) appName
|
||||||
(NSString *) path
|
path:(NSString *) path
|
||||||
value:
|
props:(NSDictionary *) props
|
||||||
(NSDictionary *) value
|
resolver:(RCTPromiseResolveBlock) resolve
|
||||||
callback:
|
rejecter:(RCTPromiseRejectBlock) reject) {
|
||||||
(RCTResponseSenderBlock) callback) {
|
FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path];
|
||||||
FIRDatabaseReference *ref = [self getPathRef:path];
|
[ref updateChildValues:props withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
|
||||||
[ref updateChildValues:value withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
|
[RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error];
|
||||||
[self handleCallback:@"update" callback:callback databaseError:error];
|
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(remove:
|
RCT_EXPORT_METHOD(remove:(NSString *) appName
|
||||||
(NSString *) path
|
path:(NSString *) path
|
||||||
callback:
|
resolver:(RCTPromiseResolveBlock) resolve
|
||||||
(RCTResponseSenderBlock) callback) {
|
rejecter:(RCTPromiseRejectBlock) reject) {
|
||||||
FIRDatabaseReference *ref = [self getPathRef:path];
|
FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path];
|
||||||
[ref removeValueWithCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
|
[ref removeValueWithCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
|
||||||
[self handleCallback:@"remove" callback:callback databaseError:error];
|
[RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(push:
|
RCT_EXPORT_METHOD(once:(NSString *) appName
|
||||||
(NSString *) path
|
refId:(nonnull NSNumber *) refId
|
||||||
data:
|
path:(NSString *) path
|
||||||
(NSDictionary *) data
|
modifiers:(NSArray *) modifiers
|
||||||
callback:
|
eventName:(NSString *) eventName
|
||||||
(RCTResponseSenderBlock) callback) {
|
resolver:(RCTPromiseResolveBlock) resolve
|
||||||
FIRDatabaseReference *ref = [self getPathRef:path];
|
rejecter:(RCTPromiseRejectBlock) reject) {
|
||||||
FIRDatabaseReference *newRef = [ref childByAutoId];
|
RNFirebaseDatabaseReference *ref = [self getInternalReferenceForApp:appName refId:refId path:path modifiers:modifiers keep:false];
|
||||||
|
[ref addSingleEventHandler:eventName resolver:resolve rejecter:reject];
|
||||||
|
}
|
||||||
|
|
||||||
NSURL *url = [NSURL URLWithString:newRef.URL];
|
/*
|
||||||
NSString *newPath = [url path];
|
* 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);
|
||||||
|
} else {
|
||||||
|
resolve([NSNull null]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ([data count] > 0) {
|
+ (FIRDatabase *) getDatabaseForApp:(NSString *) appName {
|
||||||
[newRef setValue:[data valueForKey:@"value"] withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
|
FIRApp *app = [FIRApp appNamed:appName];
|
||||||
|
return [FIRDatabase databaseForApp:app];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (FIRDatabaseReference *) getReferenceForAppPath:(NSString *) appName
|
||||||
|
path:(NSString *) path {
|
||||||
|
return [[RNFirebaseDatabase getDatabaseForApp:appName] referenceWithPath:path];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (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) {
|
if (error != nil) {
|
||||||
// Error handling
|
[resultMap setValue:@"error" forKey:@"type"];
|
||||||
NSDictionary *evt = @{@"code": @([error code]), @"details": [error debugDescription], @"message": [error localizedDescription], @"description": [error description]};
|
[resultMap setValue:[RNFirebaseDatabase getJSError:error] forKey:@"error"];
|
||||||
|
// TODO: timeout error on iOS
|
||||||
callback(@[evt]);
|
|
||||||
} else {
|
} else {
|
||||||
callback(@[[NSNull null], @{@"status": @"success", @"ref": newPath}]);
|
[resultMap setValue:@"complete" forKey:@"type"];
|
||||||
}
|
[resultMap setValue:[RNFirebaseDatabaseReference snapshotToDict:snapshot] forKey:@"snapshot"];
|
||||||
}];
|
|
||||||
} else {
|
|
||||||
callback(@[[NSNull null], @{@"status": @"success", @"ref": newPath}]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return resultMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* TODO
|
||||||
RCT_EXPORT_METHOD(on:
|
RCT_EXPORT_METHOD(on:
|
||||||
(nonnull
|
(nonnull
|
||||||
NSNumber *) refId
|
NSNumber *) refId
|
||||||
@ -231,17 +398,6 @@ RCT_EXPORT_METHOD(on:
|
|||||||
callback(@[[NSNull null], @{@"status": @"success", @"refId": refId, @"handle": path}]);
|
callback(@[[NSNull null], @{@"status": @"success", @"refId": refId, @"handle": path}]);
|
||||||
}
|
}
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(once:
|
|
||||||
(nonnull
|
|
||||||
NSNumber *) refId
|
|
||||||
path:(NSString *) path
|
|
||||||
modifiers:(NSArray *) modifiers
|
|
||||||
eventName:(NSString *) eventName
|
|
||||||
callback:(RCTResponseSenderBlock) callback) {
|
|
||||||
RNFirebaseDatabaseReference *ref = [self getDBHandle:refId path:path modifiers:modifiers];
|
|
||||||
[ref addSingleEventHandler:eventName callback:callback];
|
|
||||||
}
|
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(off:
|
RCT_EXPORT_METHOD(off:
|
||||||
(nonnull
|
(nonnull
|
||||||
NSNumber *) refId
|
NSNumber *) refId
|
||||||
@ -261,60 +417,6 @@ RCT_EXPORT_METHOD(off:
|
|||||||
callback(@[[NSNull null], @{@"status": @"success", @"refId": refId,}]);
|
callback(@[[NSNull null], @{@"status": @"success", @"refId": refId,}]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// On disconnect
|
|
||||||
RCT_EXPORT_METHOD(onDisconnectSet:
|
|
||||||
(NSString *) path
|
|
||||||
props:
|
|
||||||
(NSDictionary *) props
|
|
||||||
callback:
|
|
||||||
(RCTResponseSenderBlock) callback) {
|
|
||||||
FIRDatabaseReference *ref = [self getPathRef:path];
|
|
||||||
[ref onDisconnectSetValue:props[@"value"] withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
|
|
||||||
[self handleCallback:@"onDisconnectSetObject" callback:callback databaseError:error];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(onDisconnectRemove:
|
|
||||||
(NSString *) path
|
|
||||||
callback:
|
|
||||||
(RCTResponseSenderBlock) callback) {
|
|
||||||
FIRDatabaseReference *ref = [self getPathRef:path];
|
|
||||||
[ref onDisconnectRemoveValueWithCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
|
|
||||||
[self handleCallback:@"onDisconnectRemove" callback:callback databaseError:error];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(onDisconnectCancel:
|
|
||||||
(NSString *) path
|
|
||||||
callback:
|
|
||||||
(RCTResponseSenderBlock) callback) {
|
|
||||||
FIRDatabaseReference *ref = [self getPathRef:path];
|
|
||||||
[ref cancelDisconnectOperationsWithCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
|
|
||||||
[self handleCallback:@"onDisconnectCancel" callback:callback databaseError:error];
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(goOffline) {
|
|
||||||
[FIRDatabase database].goOffline;
|
|
||||||
}
|
|
||||||
|
|
||||||
RCT_EXPORT_METHOD(goOnline) {
|
|
||||||
[FIRDatabase database].goOnline;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (FIRDatabaseReference *)getPathRef:(NSString *)path {
|
|
||||||
return [[[FIRDatabase database] reference] child:path];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)handleCallback:(NSString *)methodName callback:(RCTResponseSenderBlock)callback databaseError:(NSError *)databaseError {
|
|
||||||
if (databaseError != nil) {
|
|
||||||
NSDictionary *evt = @{@"code": @([databaseError code]), @"details": [databaseError debugDescription], @"message": [databaseError localizedDescription], @"description": [databaseError description]};
|
|
||||||
callback(@[evt]);
|
|
||||||
} else {
|
|
||||||
callback(@[[NSNull null], @{@"status": @"success", @"method": methodName}]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (RNFirebaseDatabaseReference *)getDBHandle:(NSNumber *)refId path:(NSString *)path modifiers:(NSArray *)modifiers {
|
- (RNFirebaseDatabaseReference *)getDBHandle:(NSNumber *)refId path:(NSString *)path modifiers:(NSArray *)modifiers {
|
||||||
RNFirebaseDatabaseReference *ref = _dbReferences[refId];
|
RNFirebaseDatabaseReference *ref = _dbReferences[refId];
|
||||||
@ -324,7 +426,7 @@ RCT_EXPORT_METHOD(goOnline) {
|
|||||||
_dbReferences[refId] = ref;
|
_dbReferences[refId] = ref;
|
||||||
}
|
}
|
||||||
return ref;
|
return ref;
|
||||||
}
|
} */
|
||||||
|
|
||||||
// Not sure how to get away from this... yet
|
// Not sure how to get away from this... yet
|
||||||
- (NSArray<NSString *> *)supportedEvents {
|
- (NSArray<NSString *> *)supportedEvents {
|
||||||
|
@ -8,13 +8,14 @@
|
|||||||
@interface RNFirebaseDatabaseReference : NSObject
|
@interface RNFirebaseDatabaseReference : NSObject
|
||||||
@property RCTEventEmitter *emitter;
|
@property RCTEventEmitter *emitter;
|
||||||
@property FIRDatabaseQuery *query;
|
@property FIRDatabaseQuery *query;
|
||||||
|
@property NSString *app;
|
||||||
@property NSNumber *refId;
|
@property NSNumber *refId;
|
||||||
@property NSString *path;
|
@property NSString *path;
|
||||||
@property NSMutableDictionary *listeners;
|
@property NSMutableDictionary *listeners;
|
||||||
|
|
||||||
- (id)initWithPathAndModifiers:(RCTEventEmitter *)emitter database:(FIRDatabase *)database refId:(NSNumber *)refId path:(NSString *)path modifiers:(NSArray *)modifiers;
|
- (id)initWithPathAndModifiers:(RCTEventEmitter *)emitter app:(NSString *)app refId:(NSNumber *)refId refPath:(NSString *)refPath modifiers:(NSArray *)modifiers;
|
||||||
- (void)addEventHandler:(NSNumber *)listenerId eventName:(NSString *)eventName;
|
- (void)addEventHandler:(NSNumber *)listenerId eventName:(NSString *)eventName;
|
||||||
- (void)addSingleEventHandler:(NSString *)eventName callback:(RCTResponseSenderBlock)callback;
|
- (void)addSingleEventHandler:(NSString *)eventName resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject;
|
||||||
- (void)removeEventHandler:(NSNumber *)listenerId eventName:(NSString *)eventName;
|
- (void)removeEventHandler:(NSNumber *)listenerId eventName:(NSString *)eventName;
|
||||||
- (BOOL)hasListeners;
|
- (BOOL)hasListeners;
|
||||||
+ (NSDictionary *)snapshotToDict:(FIRDataSnapshot *)snapshot;
|
+ (NSDictionary *)snapshotToDict:(FIRDataSnapshot *)snapshot;
|
||||||
|
@ -1,18 +1,27 @@
|
|||||||
#import "RNFirebaseDatabaseReference.h"
|
#import "RNFirebaseDatabaseReference.h"
|
||||||
|
|
||||||
#if __has_include(<FirebaseDatabase/FIRDatabase.h>)
|
#if __has_include(<FirebaseDatabase/FIRDatabase.h>)
|
||||||
|
#import "RNFirebaseDatabase.h"
|
||||||
#import "RNFirebaseEvents.h"
|
#import "RNFirebaseEvents.h"
|
||||||
|
|
||||||
@implementation RNFirebaseDatabaseReference
|
@implementation RNFirebaseDatabaseReference
|
||||||
|
|
||||||
- (id)initWithPathAndModifiers:(RCTEventEmitter *)emitter database:(FIRDatabase *)database refId:(NSNumber *)refId path:(NSString *)path modifiers:(NSArray *)modifiers {
|
- (id)initWithPathAndModifiers:(RCTEventEmitter *)emitter
|
||||||
|
app:(NSString *) app
|
||||||
|
refId:(NSNumber *) refId
|
||||||
|
refPath:(NSString *) refPath
|
||||||
|
modifiers:(NSArray *) modifiers {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (self) {
|
if (self) {
|
||||||
_emitter = emitter;
|
_emitter = emitter;
|
||||||
|
_app = app;
|
||||||
_refId = refId;
|
_refId = refId;
|
||||||
_path = path;
|
_path = refPath;
|
||||||
_query = [self buildQueryAtPathWithModifiers:database path:path modifiers:modifiers];
|
|
||||||
|
// TODO: Only create if needed
|
||||||
_listeners = [[NSMutableDictionary alloc] init];
|
_listeners = [[NSMutableDictionary alloc] init];
|
||||||
|
|
||||||
|
_query = [self buildQueryAtPathWithModifiers:refPath modifiers:modifiers];
|
||||||
}
|
}
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
@ -36,15 +45,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)addSingleEventHandler:(NSString *)eventName callback:(RCTResponseSenderBlock)callback {
|
- (void)addSingleEventHandler:(NSString *)eventName
|
||||||
|
resolver:(RCTPromiseResolveBlock) resolve
|
||||||
|
rejecter:(RCTPromiseRejectBlock) reject {
|
||||||
FIRDataEventType firDataEventType = (FIRDataEventType)[self eventTypeFromName:eventName];
|
FIRDataEventType firDataEventType = (FIRDataEventType)[self eventTypeFromName:eventName];
|
||||||
|
|
||||||
[_query observeSingleEventOfType:firDataEventType andPreviousSiblingKeyWithBlock:^(FIRDataSnapshot *_Nonnull snapshot, NSString *_Nullable previousChildName) {
|
[_query observeSingleEventOfType:firDataEventType andPreviousSiblingKeyWithBlock:^(FIRDataSnapshot *_Nonnull snapshot, NSString *_Nullable previousChildName) {
|
||||||
NSDictionary *props = [RNFirebaseDatabaseReference snapshotToDict:snapshot];
|
NSDictionary *data = [RNFirebaseDatabaseReference snapshotToDictionary:eventName path:_path dataSnapshot:snapshot previousChildName:previousChildName refId:_refId listenerId:0];
|
||||||
callback(@[[NSNull null], @{@"eventName": eventName, @"path": _path, @"refId": _refId, @"snapshot": props, @"previousChildName": previousChildName != nil ? previousChildName : [NSNull null]}]);
|
resolve(data);
|
||||||
} withCancelBlock:^(NSError *_Nonnull error) {
|
} withCancelBlock:^(NSError *_Nonnull error) {
|
||||||
NSLog(@"Error onDBEventOnce: %@", [error debugDescription]);
|
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]}]);
|
[RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error];
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,6 +67,45 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (NSDictionary *) snapshotToDictionary:(NSString *) eventName
|
||||||
|
path:(NSString *) path
|
||||||
|
dataSnapshot:(FIRDataSnapshot *) dataSnapshot
|
||||||
|
previousChildName:(NSString *) previousChildName
|
||||||
|
refId:(NSNumber *) refId
|
||||||
|
listenerId:(NSNumber *) listenerId {
|
||||||
|
NSMutableDictionary *snapshot = [[NSMutableDictionary alloc] init];
|
||||||
|
NSMutableDictionary *eventMap = [[NSMutableDictionary alloc] init];
|
||||||
|
|
||||||
|
[snapshot setValue:dataSnapshot.key forKey:@"key"];
|
||||||
|
[snapshot setValue:@(dataSnapshot.exists) forKey:@"exists"];
|
||||||
|
[snapshot setValue:@(dataSnapshot.hasChildren) forKey:@"hasChildren"];
|
||||||
|
[snapshot setValue:@(dataSnapshot.childrenCount) forKey:@"childrenCount"];
|
||||||
|
[snapshot setValue:dataSnapshot.value forKey:@"value"];
|
||||||
|
[snapshot setValue:[RNFirebaseDatabaseReference getChildKeys:dataSnapshot] forKey:@"childKeys"];
|
||||||
|
[snapshot setValue:dataSnapshot.priority forKey:@"priority"];
|
||||||
|
|
||||||
|
[eventMap setValue:refId forKey:@"refId"];
|
||||||
|
[eventMap setValue:path forKey:@"path"];
|
||||||
|
[eventMap setValue:snapshot forKey:@"snapshot"];
|
||||||
|
[eventMap setValue:eventName forKey:@"eventName"];
|
||||||
|
[eventMap setValue:listenerId forKey:@"listenerId"];
|
||||||
|
[eventMap setValue:previousChildName forKey:@"previousChildName"];
|
||||||
|
|
||||||
|
return eventMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSMutableArray *) getChildKeys:(FIRDataSnapshot *) snapshot {
|
||||||
|
NSMutableArray *childKeys = [NSMutableArray array];
|
||||||
|
if (snapshot.childrenCount > 0) {
|
||||||
|
NSEnumerator *children = [snapshot children];
|
||||||
|
FIRDataSnapshot *child;
|
||||||
|
while (child = [children nextObject]) {
|
||||||
|
[childKeys addObject:child.key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return childKeys;
|
||||||
|
}
|
||||||
|
|
||||||
+ (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"];
|
||||||
@ -103,8 +153,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (FIRDatabaseQuery *)buildQueryAtPathWithModifiers:(FIRDatabase *)database path:(NSString *)path modifiers:(NSArray *)modifiers {
|
- (FIRDatabaseQuery *)buildQueryAtPathWithModifiers:(NSString *) path
|
||||||
FIRDatabaseQuery *query = [[database reference] child:path];
|
modifiers:(NSArray *)modifiers {
|
||||||
|
FIRDatabase *firebaseDatabase = [RNFirebaseDatabase getDatabaseForApp:_app];
|
||||||
|
FIRDatabaseQuery *query = [[firebaseDatabase reference] child:path];
|
||||||
|
|
||||||
for (NSDictionary *modifier in modifiers) {
|
for (NSDictionary *modifier in modifiers) {
|
||||||
NSString *type = [modifier valueForKey:@"type"];
|
NSString *type = [modifier valueForKey:@"type"];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user