2017-09-28 12:48:28 +00:00
|
|
|
#import "RNFirebaseFirestoreDocumentReference.h"
|
|
|
|
|
|
|
|
@implementation RNFirebaseFirestoreDocumentReference
|
|
|
|
|
2017-10-03 16:23:28 +00:00
|
|
|
#if __has_include(<FirebaseFirestore/FirebaseFirestore.h>)
|
2017-09-28 12:48:28 +00:00
|
|
|
|
2017-10-03 09:12:25 +00:00
|
|
|
static NSMutableDictionary *_listeners;
|
|
|
|
|
2017-10-02 14:45:07 +00:00
|
|
|
- (id)initWithPath:(RCTEventEmitter *)emitter
|
|
|
|
app:(NSString *) app
|
2017-09-28 12:48:28 +00:00
|
|
|
path:(NSString *) path {
|
|
|
|
self = [super init];
|
|
|
|
if (self) {
|
2017-10-02 14:45:07 +00:00
|
|
|
_emitter = emitter;
|
2017-09-28 12:48:28 +00:00
|
|
|
_app = app;
|
|
|
|
_path = path;
|
|
|
|
_ref = [[RNFirebaseFirestore getFirestoreForApp:_app] documentWithPath:_path];
|
2017-10-03 09:12:25 +00:00
|
|
|
}
|
|
|
|
// Initialise the static listeners object if required
|
|
|
|
if (!_listeners) {
|
2017-10-02 14:45:07 +00:00
|
|
|
_listeners = [[NSMutableDictionary alloc] init];
|
2017-09-28 12:48:28 +00:00
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)collections:(RCTPromiseResolveBlock) resolve
|
|
|
|
rejecter:(RCTPromiseRejectBlock) reject {
|
|
|
|
// Not supported on iOS
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)create:(NSDictionary *) data
|
|
|
|
resolver:(RCTPromiseResolveBlock) resolve
|
|
|
|
rejecter:(RCTPromiseRejectBlock) reject {
|
|
|
|
// Not supported on iOS out of the box
|
|
|
|
}
|
|
|
|
|
2017-10-05 09:18:24 +00:00
|
|
|
- (void)delete:(RCTPromiseResolveBlock) resolve
|
2017-09-28 12:48:28 +00:00
|
|
|
rejecter:(RCTPromiseRejectBlock) reject {
|
|
|
|
[_ref deleteDocumentWithCompletion:^(NSError * _Nullable error) {
|
|
|
|
[RNFirebaseFirestoreDocumentReference handleWriteResponse:error resolver:resolve rejecter:reject];
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)get:(RCTPromiseResolveBlock) resolve
|
|
|
|
rejecter:(RCTPromiseRejectBlock) reject {
|
|
|
|
[_ref getDocumentWithCompletion:^(FIRDocumentSnapshot * _Nullable snapshot, NSError * _Nullable error) {
|
|
|
|
if (error) {
|
|
|
|
[RNFirebaseFirestore promiseRejectException:reject error:error];
|
|
|
|
} else {
|
|
|
|
NSDictionary *data = [RNFirebaseFirestoreDocumentReference snapshotToDictionary:snapshot];
|
|
|
|
resolve(data);
|
|
|
|
}
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
2017-10-03 09:12:25 +00:00
|
|
|
+ (void)offSnapshot:(NSString *) listenerId {
|
2017-10-02 14:45:07 +00:00
|
|
|
id<FIRListenerRegistration> listener = _listeners[listenerId];
|
|
|
|
if (listener) {
|
|
|
|
[_listeners removeObjectForKey:listenerId];
|
|
|
|
[listener remove];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-06 11:00:40 +00:00
|
|
|
- (void)onSnapshot:(NSString *) listenerId
|
|
|
|
docListenOptions:(NSDictionary *) docListenOptions {
|
2017-10-02 14:45:07 +00:00
|
|
|
if (_listeners[listenerId] == nil) {
|
|
|
|
id listenerBlock = ^(FIRDocumentSnapshot * _Nullable snapshot, NSError * _Nullable error) {
|
|
|
|
if (error) {
|
|
|
|
id<FIRListenerRegistration> listener = _listeners[listenerId];
|
|
|
|
if (listener) {
|
|
|
|
[_listeners removeObjectForKey:listenerId];
|
|
|
|
[listener remove];
|
|
|
|
}
|
|
|
|
[self handleDocumentSnapshotError:listenerId error:error];
|
|
|
|
} else {
|
|
|
|
[self handleDocumentSnapshotEvent:listenerId documentSnapshot:snapshot];
|
|
|
|
}
|
|
|
|
};
|
2017-10-06 11:00:40 +00:00
|
|
|
FIRDocumentListenOptions *options = [[FIRDocumentListenOptions alloc] init];
|
|
|
|
if (docListenOptions && docListenOptions[@"includeMetadataChanges"]) {
|
|
|
|
[options includeMetadataChanges:TRUE];
|
|
|
|
}
|
|
|
|
id<FIRListenerRegistration> listener = [_ref addSnapshotListenerWithOptions:options listener:listenerBlock];
|
2017-10-02 14:45:07 +00:00
|
|
|
_listeners[listenerId] = listener;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-28 12:48:28 +00:00
|
|
|
- (void)set:(NSDictionary *) data
|
|
|
|
options:(NSDictionary *) options
|
|
|
|
resolver:(RCTPromiseResolveBlock) resolve
|
|
|
|
rejecter:(RCTPromiseRejectBlock) reject {
|
|
|
|
if (options && options[@"merge"]) {
|
|
|
|
[_ref setData:data options:[FIRSetOptions merge] completion:^(NSError * _Nullable error) {
|
|
|
|
[RNFirebaseFirestoreDocumentReference handleWriteResponse:error resolver:resolve rejecter:reject];
|
|
|
|
}];
|
|
|
|
} else {
|
|
|
|
[_ref setData:data completion:^(NSError * _Nullable error) {
|
|
|
|
[RNFirebaseFirestoreDocumentReference handleWriteResponse:error resolver:resolve rejecter:reject];
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)update:(NSDictionary *) data
|
|
|
|
resolver:(RCTPromiseResolveBlock) resolve
|
|
|
|
rejecter:(RCTPromiseRejectBlock) reject {
|
|
|
|
[_ref updateData:data completion:^(NSError * _Nullable error) {
|
|
|
|
[RNFirebaseFirestoreDocumentReference handleWriteResponse:error resolver:resolve rejecter:reject];
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
2017-10-02 14:45:07 +00:00
|
|
|
- (BOOL)hasListeners {
|
|
|
|
return [[_listeners allKeys] count] > 0;
|
|
|
|
}
|
|
|
|
|
2017-09-28 12:48:28 +00:00
|
|
|
+ (void)handleWriteResponse:(NSError *) error
|
|
|
|
resolver:(RCTPromiseResolveBlock) resolve
|
|
|
|
rejecter:(RCTPromiseRejectBlock) reject {
|
|
|
|
if (error) {
|
|
|
|
[RNFirebaseFirestore promiseRejectException:reject error:error];
|
|
|
|
} else {
|
2017-10-05 09:18:24 +00:00
|
|
|
resolve(nil);
|
2017-09-28 12:48:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
+ (NSDictionary *)snapshotToDictionary:(FIRDocumentSnapshot *)documentSnapshot {
|
|
|
|
NSMutableDictionary *snapshot = [[NSMutableDictionary alloc] init];
|
|
|
|
[snapshot setValue:documentSnapshot.reference.path forKey:@"path"];
|
2017-09-28 16:48:13 +00:00
|
|
|
if (documentSnapshot.exists) {
|
|
|
|
[snapshot setValue:documentSnapshot.data forKey:@"data"];
|
|
|
|
}
|
2017-10-05 09:18:24 +00:00
|
|
|
if (documentSnapshot.metadata) {
|
|
|
|
NSMutableDictionary *metadata = [[NSMutableDictionary alloc] init];
|
|
|
|
[metadata setValue:@(documentSnapshot.metadata.fromCache) forKey:@"fromCache"];
|
|
|
|
[metadata setValue:@(documentSnapshot.metadata.hasPendingWrites) forKey:@"hasPendingWrites"];
|
|
|
|
[snapshot setValue:metadata forKey:@"metadata"];
|
|
|
|
}
|
2017-09-28 12:48:28 +00:00
|
|
|
return snapshot;
|
|
|
|
}
|
|
|
|
|
2017-10-03 09:12:25 +00:00
|
|
|
- (void)handleDocumentSnapshotError:(NSString *)listenerId
|
2017-10-02 14:45:07 +00:00
|
|
|
error:(NSError *)error {
|
|
|
|
NSMutableDictionary *event = [[NSMutableDictionary alloc] init];
|
|
|
|
[event setValue:_app forKey:@"appName"];
|
|
|
|
[event setValue:_path forKey:@"path"];
|
|
|
|
[event setValue:listenerId forKey:@"listenerId"];
|
|
|
|
[event setValue:[RNFirebaseFirestore getJSError:error] forKey:@"error"];
|
2017-10-03 16:23:28 +00:00
|
|
|
|
2017-10-02 14:45:07 +00:00
|
|
|
[_emitter sendEventWithName:FIRESTORE_DOCUMENT_SYNC_EVENT body:event];
|
|
|
|
}
|
|
|
|
|
2017-10-03 09:12:25 +00:00
|
|
|
- (void)handleDocumentSnapshotEvent:(NSString *)listenerId
|
2017-10-02 14:45:07 +00:00
|
|
|
documentSnapshot:(FIRDocumentSnapshot *)documentSnapshot {
|
|
|
|
NSMutableDictionary *event = [[NSMutableDictionary alloc] init];
|
|
|
|
[event setValue:_app forKey:@"appName"];
|
|
|
|
[event setValue:_path forKey:@"path"];
|
|
|
|
[event setValue:listenerId forKey:@"listenerId"];
|
2017-10-03 09:12:25 +00:00
|
|
|
[event setValue:[RNFirebaseFirestoreDocumentReference snapshotToDictionary:documentSnapshot] forKey:@"documentSnapshot"];
|
2017-10-03 16:23:28 +00:00
|
|
|
|
2017-10-02 14:45:07 +00:00
|
|
|
[_emitter sendEventWithName:FIRESTORE_DOCUMENT_SYNC_EVENT body:event];
|
|
|
|
}
|
|
|
|
|
2017-09-28 12:48:28 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
@end
|