2
0
mirror of synced 2025-02-18 17:28:24 +00:00

[ios][database] New implementation for off and on to match Android

This commit is contained in:
Chris Bianca 2017-08-22 17:29:02 +01:00
parent aebd1835bc
commit 1230bd7108
5 changed files with 12687 additions and 278 deletions

View File

@ -18,6 +18,8 @@
+ (FIRDatabase *)getDatabaseForApp:(NSString *)appName; + (FIRDatabase *)getDatabaseForApp:(NSString *)appName;
+ (NSDictionary *)getJSError:(NSError *)nativeError;
+ (NSString *)getMessageWithService:(NSString *)message service:(NSString *)service fullCode:(NSString *)fullCode; + (NSString *)getMessageWithService:(NSString *)message service:(NSString *)service fullCode:(NSString *)fullCode;
+ (NSString *)getCodeWithService:(NSString *)service code:(NSString *)code; + (NSString *)getCodeWithService:(NSString *)service code:(NSString *)code;

View File

@ -21,42 +21,31 @@ RCT_EXPORT_MODULE();
return self; return self;
} }
RCT_EXPORT_METHOD(goOnline: RCT_EXPORT_METHOD(goOnline:(NSString *) appName) {
(NSString *) appName) {
[[RNFirebaseDatabase getDatabaseForApp:appName] goOnline]; [[RNFirebaseDatabase getDatabaseForApp:appName] goOnline];
} }
RCT_EXPORT_METHOD(goOffline: RCT_EXPORT_METHOD(goOffline:(NSString *) appName) {
(NSString *) appName) {
[[RNFirebaseDatabase getDatabaseForApp:appName] goOffline]; [[RNFirebaseDatabase getDatabaseForApp:appName] goOffline];
} }
RCT_EXPORT_METHOD(setPersistence: RCT_EXPORT_METHOD(setPersistence:(NSString *) appName
(NSString *) appName state:(BOOL) state) {
state:
(BOOL) state) {
[RNFirebaseDatabase getDatabaseForApp:appName].persistenceEnabled = state; [RNFirebaseDatabase getDatabaseForApp:appName].persistenceEnabled = state;
} }
RCT_EXPORT_METHOD(keepSynced: RCT_EXPORT_METHOD(keepSynced:(NSString *) appName
(NSString *) appName key:(NSString *) key
refId: path:(NSString *) path
(nonnull modifiers:(NSArray *) modifiers
NSNumber *) refId state:(BOOL) state) {
path:(NSString *) path FIRDatabaseQuery *query = [self getInternalReferenceForApp:appName key:key path:path modifiers:modifiers keep:false].query;
modifiers:(NSArray *) modifiers
state:(BOOL) state) {
FIRDatabaseQuery *query = [self getInternalReferenceForApp:appName refId:refId path:path modifiers:modifiers keep:false].query;
[query keepSynced:state]; [query keepSynced:state];
} }
RCT_EXPORT_METHOD(transactionTryCommit: RCT_EXPORT_METHOD(transactionTryCommit:(NSString *) appName
(NSString *) appName transactionId:(nonnull NSNumber *) transactionId
transactionId: updates:(NSDictionary *) updates) {
(nonnull
NSNumber *) transactionId
updates:(NSDictionary *) updates) {
__block NSMutableDictionary *transactionState; __block NSMutableDictionary *transactionState;
dispatch_sync(_transactionQueue, ^{ dispatch_sync(_transactionQueue, ^{
@ -83,14 +72,10 @@ RCT_EXPORT_METHOD(transactionTryCommit:
} }
RCT_EXPORT_METHOD(transactionStart: RCT_EXPORT_METHOD(transactionStart:(NSString *) appName
(NSString *) appName path:(NSString *) path
path: transactionId:(nonnull NSNumber *) transactionId
(NSString *) path applyLocally:(BOOL) applyLocally) {
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);
@ -136,160 +121,132 @@ RCT_EXPORT_METHOD(transactionStart:
}); });
} }
RCT_EXPORT_METHOD(onDisconnectSet: RCT_EXPORT_METHOD(onDisconnectSet:(NSString *) appName
(NSString *) appName path:(NSString *) path
path: props:(NSDictionary *) props
(NSString *) path resolver:(RCTPromiseResolveBlock) resolve
props: rejecter:(RCTPromiseRejectBlock) reject) {
(NSDictionary *) props
resolver:
(RCTPromiseResolveBlock) resolve
rejecter:
(RCTPromiseRejectBlock) reject) {
FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path]; FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path];
[ref onDisconnectSetValue:props[@"value"] withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) { [ref onDisconnectSetValue:props[@"value"] withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
[RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error]; [RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error];
}]; }];
} }
RCT_EXPORT_METHOD(onDisconnectUpdate: RCT_EXPORT_METHOD(onDisconnectUpdate:(NSString *) appName
(NSString *) appName path:(NSString *) path
path: props:(NSDictionary *) props
(NSString *) path resolver:(RCTPromiseResolveBlock) resolve
props: rejecter:(RCTPromiseRejectBlock) reject) {
(NSDictionary *) props
resolver:
(RCTPromiseResolveBlock) resolve
rejecter:
(RCTPromiseRejectBlock) reject) {
FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path]; FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path];
[ref onDisconnectUpdateChildValues:props withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) { [ref onDisconnectUpdateChildValues:props withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
[RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error]; [RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error];
}]; }];
} }
RCT_EXPORT_METHOD(onDisconnectRemove: RCT_EXPORT_METHOD(onDisconnectRemove:(NSString *) appName
(NSString *) appName path:(NSString *) path
path: resolver:(RCTPromiseResolveBlock) resolve
(NSString *) path rejecter:(RCTPromiseRejectBlock) reject) {
resolver:
(RCTPromiseResolveBlock) resolve
rejecter:
(RCTPromiseRejectBlock) reject) {
FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path]; FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path];
[ref onDisconnectRemoveValueWithCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) { [ref onDisconnectRemoveValueWithCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
[RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error]; [RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error];
}]; }];
} }
RCT_EXPORT_METHOD(onDisconnectCancel: RCT_EXPORT_METHOD(onDisconnectCancel:(NSString *) appName
(NSString *) appName path:(NSString *) path
path: resolver:(RCTPromiseResolveBlock) resolve
(NSString *) path rejecter:(RCTPromiseRejectBlock) reject) {
resolver:
(RCTPromiseResolveBlock) resolve
rejecter:
(RCTPromiseRejectBlock) reject) {
FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path]; FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path];
[ref cancelDisconnectOperationsWithCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) { [ref cancelDisconnectOperationsWithCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
[RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error]; [RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error];
}]; }];
} }
RCT_EXPORT_METHOD(set: RCT_EXPORT_METHOD(set:(NSString *) appName
(NSString *) appName path:(NSString *) path
path: props:(NSDictionary *) props
(NSString *) path resolver:(RCTPromiseResolveBlock) resolve
props: rejecter:(RCTPromiseRejectBlock) reject) {
(NSDictionary *) props
resolver:
(RCTPromiseResolveBlock) resolve
rejecter:
(RCTPromiseRejectBlock) reject) {
FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path]; FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path];
[ref setValue:[props valueForKey:@"value"] withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) { [ref setValue:[props valueForKey:@"value"] withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
[RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error]; [RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error];
}]; }];
} }
RCT_EXPORT_METHOD(setPriority: RCT_EXPORT_METHOD(setPriority:(NSString *) appName
(NSString *) appName path:(NSString *) path
path: priority:(NSDictionary *) priority
(NSString *) path resolver:(RCTPromiseResolveBlock) resolve
priority: rejecter:(RCTPromiseRejectBlock) reject) {
(NSDictionary *) priority
resolver:
(RCTPromiseResolveBlock) resolve
rejecter:
(RCTPromiseRejectBlock) reject) {
FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path]; FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path];
[ref setPriority:[priority valueForKey:@"value"] withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull ref) { [ref setPriority:[priority valueForKey:@"value"] withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull ref) {
[RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error]; [RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error];
}]; }];
} }
RCT_EXPORT_METHOD(setWithPriority: RCT_EXPORT_METHOD(setWithPriority:(NSString *) appName
(NSString *) appName path:(NSString *) path
path: data:(NSDictionary *) data
(NSString *) path priority:(NSDictionary *) priority
data: resolver:(RCTPromiseResolveBlock) resolve
(NSDictionary *) data rejecter:(RCTPromiseRejectBlock) reject) {
priority:
(NSDictionary *) priority
resolver:
(RCTPromiseResolveBlock) resolve
rejecter:
(RCTPromiseRejectBlock) reject) {
FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path]; FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path];
[ref setValue:[data valueForKey:@"value"] andPriority:[priority valueForKey:@"value"] withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull ref) { [ref setValue:[data valueForKey:@"value"] andPriority:[priority valueForKey:@"value"] withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull ref) {
[RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error]; [RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error];
}]; }];
} }
RCT_EXPORT_METHOD(update: RCT_EXPORT_METHOD(update:(NSString *) appName
(NSString *) appName path:(NSString *) path
path: props:(NSDictionary *) props
(NSString *) path resolver:(RCTPromiseResolveBlock) resolve
props: rejecter:(RCTPromiseRejectBlock) reject) {
(NSDictionary *) props
resolver:
(RCTPromiseResolveBlock) resolve
rejecter:
(RCTPromiseRejectBlock) reject) {
FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path]; FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path];
[ref updateChildValues:props withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) { [ref updateChildValues:props withCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
[RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error]; [RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error];
}]; }];
} }
RCT_EXPORT_METHOD(remove: RCT_EXPORT_METHOD(remove:(NSString *) appName
(NSString *) appName path:(NSString *) path
path: resolver:(RCTPromiseResolveBlock) resolve
(NSString *) path rejecter:(RCTPromiseRejectBlock) reject) {
resolver:
(RCTPromiseResolveBlock) resolve
rejecter:
(RCTPromiseRejectBlock) reject) {
FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path]; FIRDatabaseReference *ref = [self getReferenceForAppPath:appName path:path];
[ref removeValueWithCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) { [ref removeValueWithCompletionBlock:^(NSError *_Nullable error, FIRDatabaseReference *_Nonnull _ref) {
[RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error]; [RNFirebaseDatabase handlePromise:resolve rejecter:reject databaseError:error];
}]; }];
} }
RCT_EXPORT_METHOD(once: RCT_EXPORT_METHOD(once:(NSString *) appName
(NSString *) appName key:(NSString *) key
refId: path:(NSString *) path
(nonnull modifiers:(NSArray *) modifiers
NSNumber *) refId eventName:(NSString *) eventName
path:(NSString *) path resolver:(RCTPromiseResolveBlock) resolve
modifiers:(NSArray *) modifiers rejecter:(RCTPromiseRejectBlock) reject) {
eventName:(NSString *) eventName RNFirebaseDatabaseReference *ref = [self getInternalReferenceForApp:appName key:key path:path modifiers:modifiers keep:false];
resolver:(RCTPromiseResolveBlock) resolve [ref once:eventName resolver:resolve rejecter:reject];
rejecter:(RCTPromiseRejectBlock) reject) {
RNFirebaseDatabaseReference *ref = [self getInternalReferenceForApp:appName refId:refId path:path modifiers:modifiers keep:false];
[ref addSingleEventHandler:eventName resolver:resolve rejecter:reject];
} }
RCT_EXPORT_METHOD(on:(NSString *) appName
props:(NSDictionary *) props) {
RNFirebaseDatabaseReference *ref = [self getInternalReferenceForApp:appName key:props[@"key"] path:props[@"path"] modifiers:props[@"modifiers"] keep:false];
[ref on:props[@"eventType"] registration:props[@"registration"]];
}
RCT_EXPORT_METHOD(off:(NSString *) key
eventRegistrationKey:(NSString *) eventRegistrationKey) {
RNFirebaseDatabaseReference *ref = _dbReferences[key];
[ref removeEventListener:eventRegistrationKey];
if (![ref hasListeners]) {
[_dbReferences removeObjectForKey:key];
}
}
/* /*
* INTERNALS/UTILS * INTERNALS/UTILS
*/ */
@ -311,14 +268,14 @@ RCT_EXPORT_METHOD(once:
return [[RNFirebaseDatabase getDatabaseForApp:appName] referenceWithPath:path]; return [[RNFirebaseDatabase getDatabaseForApp:appName] referenceWithPath:path];
} }
- (RNFirebaseDatabaseReference *)getInternalReferenceForApp:(NSString *)appName refId:(NSNumber *)refId path:(NSString *)path modifiers:(NSArray *)modifiers keep:(BOOL)keep { - (RNFirebaseDatabaseReference *)getInternalReferenceForApp:(NSString *)appName key:(NSString *)key path:(NSString *)path modifiers:(NSArray *)modifiers keep:(BOOL)keep {
RNFirebaseDatabaseReference *ref = _dbReferences[refId]; RNFirebaseDatabaseReference *ref = _dbReferences[key];
if (ref == nil) { if (ref == nil) {
ref = [[RNFirebaseDatabaseReference alloc] initWithPathAndModifiers:self app:appName refId:refId refPath:path modifiers:modifiers]; ref = [[RNFirebaseDatabaseReference alloc] initWithPathAndModifiers:self app:appName key:key refPath:path modifiers:modifiers];
if (keep) { if (keep) {
_dbReferences[refId] = ref; _dbReferences[key] = ref;
} }
} }
return ref; return ref;
@ -435,47 +392,6 @@ RCT_EXPORT_METHOD(once:
return resultMap; return resultMap;
} }
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];
}
/* TODO
RCT_EXPORT_METHOD(off:
(nonnull
NSNumber *) refId
listeners:(NSArray *) listeners
callback:(RCTResponseSenderBlock) callback) {
RNFirebaseDatabaseReference *ref = _dbReferences[refId];
if (ref != nil) {
for (NSDictionary *listener in listeners) {
NSNumber *listenerId = [listener valueForKey:@"listenerId"];
NSString *eventName = [listener valueForKey:@"eventName"];
[ref removeEventHandler:listenerId eventName:eventName];
if (![ref hasListeners]) {
[_dbReferences removeObjectForKey:refId];
}
}
}
callback(@[[NSNull null], @{@"status": @"success", @"refId": refId,}]);
}
- (RNFirebaseDatabaseReference *)getDBHandle:(NSNumber *)refId path:(NSString *)path modifiers:(NSArray *)modifiers {
RNFirebaseDatabaseReference *ref = _dbReferences[refId];
if (ref == nil) {
ref = [[RNFirebaseDatabaseReference alloc] initWithPathAndModifiers:self database:[FIRDatabase database] refId:refId path:path modifiers:modifiers];
_dbReferences[refId] = ref;
}
return ref;
} */
- (NSArray<NSString *> *)supportedEvents { - (NSArray<NSString *> *)supportedEvents {
return @[DATABASE_SYNC_EVENT, DATABASE_TRANSACTION_EVENT]; return @[DATABASE_SYNC_EVENT, DATABASE_TRANSACTION_EVENT];
} }

View File

@ -12,16 +12,16 @@
@property RCTEventEmitter *emitter; @property RCTEventEmitter *emitter;
@property FIRDatabaseQuery *query; @property FIRDatabaseQuery *query;
@property NSString *app; @property NSString *app;
@property NSNumber *refId; @property NSString *key;
@property NSString *path; @property NSString *path;
@property NSMutableDictionary *listeners; @property NSMutableDictionary *listeners;
- (id)initWithPathAndModifiers:(RCTEventEmitter *)emitter app:(NSString *)app refId:(NSNumber *)refId refPath:(NSString *)refPath modifiers:(NSArray *)modifiers; - (id)initWithPathAndModifiers:(RCTEventEmitter *)emitter app:(NSString *)app key:(NSString *)key refPath:(NSString *)refPath modifiers:(NSArray *)modifiers;
- (void)addEventHandler:(NSNumber *)listenerId eventName:(NSString *)eventName; - (void)on:(NSString *) eventName registration:(NSDictionary *) registration;
- (void)addSingleEventHandler:(NSString *)eventName resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject; - (void)once:(NSString *) eventType resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject;
- (void)removeEventHandler:(NSNumber *)listenerId eventName:(NSString *)eventName; - (void)removeEventListener:(NSString *)eventRegistrationKey;
- (BOOL)hasListeners; - (BOOL)hasListeners;
+ (NSDictionary *)snapshotToDict:(FIRDataSnapshot *)snapshot; + (NSDictionary *)snapshotToDict:(FIRDataSnapshot *)dataSnapshot;
@end @end
#else #else

View File

@ -6,50 +6,52 @@
- (id)initWithPathAndModifiers:(RCTEventEmitter *)emitter - (id)initWithPathAndModifiers:(RCTEventEmitter *)emitter
app:(NSString *) app app:(NSString *) app
refId:(NSNumber *) refId key:(NSString *) key
refPath:(NSString *) refPath refPath:(NSString *) refPath
modifiers:(NSArray *) modifiers { modifiers:(NSArray *) modifiers {
self = [super init]; self = [super init];
if (self) { if (self) {
_emitter = emitter; _emitter = emitter;
_app = app; _app = app;
_refId = refId; _key = key;
_path = refPath; _path = refPath;
// TODO: Only create if needed
_listeners = [[NSMutableDictionary alloc] init]; _listeners = [[NSMutableDictionary alloc] init];
_query = [self buildQueryAtPathWithModifiers:refPath modifiers:modifiers]; _query = [self buildQueryAtPathWithModifiers:refPath modifiers:modifiers];
} }
return self; return self;
} }
- (void)addEventHandler:(NSNumber *)listenerId eventName:(NSString *)eventName { - (void)removeEventListener:(NSString *)eventRegistrationKey {
if (!_listeners[listenerId]) { FIRDatabaseHandle handle = (FIRDatabaseHandle) [_listeners[eventRegistrationKey] integerValue];
id andPreviousSiblingKeyWithBlock = ^(FIRDataSnapshot *_Nonnull snapshot, NSString *_Nullable previousChildName) { if (handle) {
NSDictionary *props = [RNFirebaseDatabaseReference snapshotToDict:snapshot]; [_query removeObserverWithHandle:handle];
[self sendJSEvent:DATABASE_SYNC_EVENT title:eventName props:@{@"eventName": eventName, @"refId": _refId, @"listenerId": listenerId, @"path": _path, @"snapshot": props, @"previousChildName": previousChildName != nil ? previousChildName : [NSNull null]}]; [_listeners removeObjectForKey:eventRegistrationKey];
};
id errorBlock = ^(NSError *_Nonnull error) {
NSLog(@"Error onDBEvent: %@", [error debugDescription]);
[self removeEventHandler:listenerId eventName:eventName];
[self getAndSendDatabaseError:error listenerId:listenerId];
};
int eventType = [self eventTypeFromName:eventName];
FIRDatabaseHandle handle = [_query observeEventType:eventType andPreviousSiblingKeyWithBlock:andPreviousSiblingKeyWithBlock withCancelBlock:errorBlock];
_listeners[listenerId] = @(handle);
} else {
NSLog(@"Warning Trying to add duplicate listener for refId: %@ listenerId: %@", _refId, listenerId);
} }
} }
- (void)addSingleEventHandler:(NSString *)eventName - (void)on:(NSString *) eventType registration:(NSDictionary *) registration {
resolver:(RCTPromiseResolveBlock) resolve NSString *eventRegistrationKey = registration[@"eventRegistrationKey"];
rejecter:(RCTPromiseRejectBlock) reject { if (![self hasEventListener:eventRegistrationKey]) {
FIRDataEventType firDataEventType = (FIRDataEventType)[self eventTypeFromName:eventName]; id andPreviousSiblingKeyWithBlock = ^(FIRDataSnapshot *_Nonnull snapshot, NSString *_Nullable previousChildName) {
[self handleDatabaseEvent:eventType registration:registration dataSnapshot:snapshot previousChildName:previousChildName];
};
id errorBlock = ^(NSError *_Nonnull error) {
NSLog(@"Error onDBEvent: %@", [error debugDescription]);
[self removeEventListener:eventRegistrationKey];
[self handleDatabaseError:registration error:error];
};
FIRDataEventType firDataEventType = (FIRDataEventType)[self eventTypeFromName:eventType];
FIRDatabaseHandle handle = [_query observeEventType:firDataEventType andPreviousSiblingKeyWithBlock:andPreviousSiblingKeyWithBlock withCancelBlock:errorBlock];
_listeners[eventRegistrationKey] = @(handle);
}
}
- (void)once:(NSString *) eventType
resolver:(RCTPromiseResolveBlock) resolve
rejecter:(RCTPromiseRejectBlock) reject {
FIRDataEventType firDataEventType = (FIRDataEventType)[self eventTypeFromName:eventType];
[_query observeSingleEventOfType:firDataEventType andPreviousSiblingKeyWithBlock:^(FIRDataSnapshot *_Nonnull snapshot, NSString *_Nullable previousChildName) { [_query observeSingleEventOfType:firDataEventType andPreviousSiblingKeyWithBlock:^(FIRDataSnapshot *_Nonnull snapshot, NSString *_Nullable previousChildName) {
NSDictionary *data = [RNFirebaseDatabaseReference snapshotToDictionary:eventName path:_path dataSnapshot:snapshot previousChildName:previousChildName refId:_refId listenerId:0]; NSDictionary *data = [RNFirebaseDatabaseReference snapshotToDictionary:snapshot previousChildName:previousChildName];
resolve(data); resolve(data);
} withCancelBlock:^(NSError *_Nonnull error) { } withCancelBlock:^(NSError *_Nonnull error) {
NSLog(@"Error onDBEventOnce: %@", [error debugDescription]); NSLog(@"Error onDBEventOnce: %@", [error debugDescription]);
@ -57,39 +59,54 @@
}]; }];
} }
- (void)removeEventHandler:(NSNumber *)listenerId eventName:(NSString *)eventName { - (void)handleDatabaseEvent:(NSString *) eventType
FIRDatabaseHandle handle = (FIRDatabaseHandle) [_listeners[listenerId] integerValue]; registration:(NSDictionary *) registration
if (handle) { dataSnapshot:(FIRDataSnapshot *) dataSnapshot
[_listeners removeObjectForKey:listenerId]; previousChildName:(NSString *) previousChildName {
[_query removeObserverWithHandle:handle]; NSMutableDictionary *event = [[NSMutableDictionary alloc] init];
} NSDictionary *data = [RNFirebaseDatabaseReference snapshotToDictionary:dataSnapshot previousChildName:previousChildName];
[event setValue:data forKey:@"data"];
[event setValue:_key forKey:@"key"];
[event setValue:eventType forKey:@"eventType"];
[event setValue:registration forKey:@"registration"];
[_emitter sendEventWithName:DATABASE_SYNC_EVENT body:event];
} }
+ (NSDictionary *) snapshotToDictionary:(NSString *) eventName - (void)handleDatabaseError:(NSDictionary *) registration
path:(NSString *) path error:(NSError *)error {
dataSnapshot:(FIRDataSnapshot *) dataSnapshot NSMutableDictionary *event = [[NSMutableDictionary alloc] init];
previousChildName:(NSString *) previousChildName [event setValue:_key forKey:@"key"];
refId:(NSNumber *) refId [event setValue:[RNFirebaseDatabase getJSError:error] forKey:@"error"];
listenerId:(NSNumber *) listenerId { [event setValue:registration forKey:@"registration"];
[_emitter sendEventWithName:DATABASE_SYNC_EVENT body:event];
}
+ (NSDictionary *)snapshotToDictionary:(FIRDataSnapshot *) dataSnapshot
previousChildName:(NSString *) previousChildName {
NSMutableDictionary *result = [[NSMutableDictionary alloc] init];
NSDictionary *snapshot = [RNFirebaseDatabaseReference snapshotToDict:dataSnapshot];
[result setValue:snapshot forKey:@"snapshot"];
[result setValue:previousChildName forKey:@"previousChildName"];
return result;
}
+ (NSDictionary *)snapshotToDict:(FIRDataSnapshot *)dataSnapshot {
NSMutableDictionary *snapshot = [[NSMutableDictionary alloc] init]; NSMutableDictionary *snapshot = [[NSMutableDictionary alloc] init];
NSMutableDictionary *eventMap = [[NSMutableDictionary alloc] init];
[snapshot setValue:dataSnapshot.key forKey:@"key"]; [snapshot setValue:dataSnapshot.key forKey:@"key"];
[snapshot setValue:@(dataSnapshot.exists) forKey:@"exists"]; [snapshot setValue:@(dataSnapshot.exists) forKey:@"exists"];
[snapshot setValue:@(dataSnapshot.hasChildren) forKey:@"hasChildren"]; [snapshot setValue:@(dataSnapshot.hasChildren) forKey:@"hasChildren"];
[snapshot setValue:@(dataSnapshot.childrenCount) forKey:@"childrenCount"]; [snapshot setValue:@(dataSnapshot.childrenCount) forKey:@"childrenCount"];
[snapshot setValue:dataSnapshot.value forKey:@"value"];
[snapshot setValue:[RNFirebaseDatabaseReference getChildKeys:dataSnapshot] forKey:@"childKeys"]; [snapshot setValue:[RNFirebaseDatabaseReference getChildKeys:dataSnapshot] forKey:@"childKeys"];
[snapshot setValue:dataSnapshot.priority forKey:@"priority"]; [snapshot setValue:dataSnapshot.priority forKey:@"priority"];
[snapshot setValue:dataSnapshot.value forKey:@"value"];
[eventMap setValue:refId forKey:@"refId"]; return snapshot;
[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 *) getChildKeys:(FIRDataSnapshot *) snapshot {
@ -104,53 +121,6 @@
return childKeys; return childKeys;
} }
+ (NSDictionary *)snapshotToDict:(FIRDataSnapshot *)snapshot {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setValue:snapshot.key forKey:@"key"];
NSDictionary *val = snapshot.value;
dict[@"value"] = val;
// Snapshot ordering
NSMutableArray *childKeys = [NSMutableArray array];
if (snapshot.childrenCount > 0) {
// Since JS does not respect object ordering of keys
// we keep a list of the keys and their ordering
// in the snapshot event
NSEnumerator *children = [snapshot children];
FIRDataSnapshot *child;
while (child = [children nextObject]) {
[childKeys addObject:child.key];
}
}
dict[@"childKeys"] = childKeys;
[dict setValue:@(snapshot.hasChildren) forKey:@"hasChildren"];
[dict setValue:@(snapshot.exists) forKey:@"exists"];
[dict setValue:@(snapshot.childrenCount) forKey:@"childrenCount"];
[dict setValue:snapshot.priority forKey:@"priority"];
return dict;
}
- (NSDictionary *)getAndSendDatabaseError:(NSError *)error listenerId:(NSNumber *)listenerId {
NSDictionary *event = @{@"eventName": DATABASE_SYNC_EVENT, @"path": _path, @"refId": _refId, @"listenerId": listenerId, @"code": @([error code]), @"details": [error debugDescription], @"message": [error localizedDescription], @"description": [error description]};
@try {
[_emitter sendEventWithName:DATABASE_SYNC_EVENT body:event];
} @catch (NSException *err) {
NSLog(@"An error occurred in getAndSendDatabaseError: %@", [err debugDescription]);
NSLog(@"Tried to send: %@ with %@", DATABASE_SYNC_EVENT, event);
}
return event;
}
- (void)sendJSEvent:(NSString *)type title:(NSString *)title props:(NSDictionary *)props {
@try {
[_emitter sendEventWithName:type body:@{@"eventName": title, @"body": props}];
} @catch (NSException *err) {
NSLog(@"An error occurred in sendJSEvent: %@", [err debugDescription]);
NSLog(@"Tried to send: %@ with %@", title, props);
}
}
- (FIRDatabaseQuery *)buildQueryAtPathWithModifiers:(NSString *) path - (FIRDatabaseQuery *)buildQueryAtPathWithModifiers:(NSString *) path
modifiers:(NSArray *)modifiers { modifiers:(NSArray *)modifiers {
FIRDatabase *firebaseDatabase = [RNFirebaseDatabase getDatabaseForApp:_app]; FIRDatabase *firebaseDatabase = [RNFirebaseDatabase getDatabaseForApp:_app];
@ -216,6 +186,10 @@
} }
} }
- (BOOL)hasEventListener:(NSString *) eventRegistrationKey {
return _listeners[eventRegistrationKey] != nil;
}
- (BOOL)hasListeners { - (BOOL)hasListeners {
return [[_listeners allKeys] count] > 0; return [[_listeners allKeys] count] > 0;
} }

12517
tests/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff