[firestore][ios] Add initial iOS functionality
This commit is contained in:
parent
f56435226d
commit
6060c36c1c
|
@ -12,6 +12,9 @@
|
|||
8323CF071F6FBD870071420B /* NativeExpressComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = 8323CF011F6FBD870071420B /* NativeExpressComponent.m */; };
|
||||
8323CF081F6FBD870071420B /* RNFirebaseAdMobBannerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8323CF031F6FBD870071420B /* RNFirebaseAdMobBannerManager.m */; };
|
||||
8323CF091F6FBD870071420B /* RNFirebaseAdMobNativeExpressManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 8323CF051F6FBD870071420B /* RNFirebaseAdMobNativeExpressManager.m */; };
|
||||
8376F7141F7C149100D45A85 /* RNFirebaseFirestoreDocumentReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 8376F70E1F7C149000D45A85 /* RNFirebaseFirestoreDocumentReference.m */; };
|
||||
8376F7151F7C149100D45A85 /* RNFirebaseFirestore.m in Sources */ = {isa = PBXBuildFile; fileRef = 8376F7101F7C149000D45A85 /* RNFirebaseFirestore.m */; };
|
||||
8376F7161F7C149100D45A85 /* RNFirebaseFirestoreCollectionReference.m in Sources */ = {isa = PBXBuildFile; fileRef = 8376F7111F7C149000D45A85 /* RNFirebaseFirestoreCollectionReference.m */; };
|
||||
839D916C1EF3E20B0077C7C8 /* RNFirebaseAdMob.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D914F1EF3E20A0077C7C8 /* RNFirebaseAdMob.m */; };
|
||||
839D916D1EF3E20B0077C7C8 /* RNFirebaseAdMobInterstitial.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91511EF3E20A0077C7C8 /* RNFirebaseAdMobInterstitial.m */; };
|
||||
839D916E1EF3E20B0077C7C8 /* RNFirebaseAdMobRewardedVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = 839D91531EF3E20A0077C7C8 /* RNFirebaseAdMobRewardedVideo.m */; };
|
||||
|
@ -50,6 +53,12 @@
|
|||
8323CF031F6FBD870071420B /* RNFirebaseAdMobBannerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseAdMobBannerManager.m; sourceTree = "<group>"; };
|
||||
8323CF041F6FBD870071420B /* RNFirebaseAdMobNativeExpressManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseAdMobNativeExpressManager.h; sourceTree = "<group>"; };
|
||||
8323CF051F6FBD870071420B /* RNFirebaseAdMobNativeExpressManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseAdMobNativeExpressManager.m; sourceTree = "<group>"; };
|
||||
8376F70E1F7C149000D45A85 /* RNFirebaseFirestoreDocumentReference.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseFirestoreDocumentReference.m; sourceTree = "<group>"; };
|
||||
8376F70F1F7C149000D45A85 /* RNFirebaseFirestore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseFirestore.h; sourceTree = "<group>"; };
|
||||
8376F7101F7C149000D45A85 /* RNFirebaseFirestore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseFirestore.m; sourceTree = "<group>"; };
|
||||
8376F7111F7C149000D45A85 /* RNFirebaseFirestoreCollectionReference.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNFirebaseFirestoreCollectionReference.m; sourceTree = "<group>"; };
|
||||
8376F7121F7C149000D45A85 /* RNFirebaseFirestoreDocumentReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseFirestoreDocumentReference.h; sourceTree = "<group>"; };
|
||||
8376F7131F7C149000D45A85 /* RNFirebaseFirestoreCollectionReference.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseFirestoreCollectionReference.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>"; };
|
||||
839D91501EF3E20A0077C7C8 /* RNFirebaseAdMobInterstitial.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNFirebaseAdMobInterstitial.h; sourceTree = "<group>"; };
|
||||
|
@ -105,6 +114,7 @@
|
|||
839D915A1EF3E20A0077C7C8 /* config */,
|
||||
839D915D1EF3E20A0077C7C8 /* crash */,
|
||||
839D91601EF3E20A0077C7C8 /* database */,
|
||||
8376F70D1F7C141500D45A85 /* firestore */,
|
||||
839D91631EF3E20A0077C7C8 /* messaging */,
|
||||
839D91661EF3E20A0077C7C8 /* perf */,
|
||||
839D91691EF3E20A0077C7C8 /* storage */,
|
||||
|
@ -115,6 +125,20 @@
|
|||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
8376F70D1F7C141500D45A85 /* firestore */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8376F70F1F7C149000D45A85 /* RNFirebaseFirestore.h */,
|
||||
8376F7101F7C149000D45A85 /* RNFirebaseFirestore.m */,
|
||||
8376F7131F7C149000D45A85 /* RNFirebaseFirestoreCollectionReference.h */,
|
||||
8376F7111F7C149000D45A85 /* RNFirebaseFirestoreCollectionReference.m */,
|
||||
8376F7121F7C149000D45A85 /* RNFirebaseFirestoreDocumentReference.h */,
|
||||
8376F70E1F7C149000D45A85 /* RNFirebaseFirestoreDocumentReference.m */,
|
||||
);
|
||||
name = firestore;
|
||||
path = RNFirebase/firestore;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
839D914D1EF3E20A0077C7C8 /* admob */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -277,9 +301,12 @@
|
|||
files = (
|
||||
839D916E1EF3E20B0077C7C8 /* RNFirebaseAdMobRewardedVideo.m in Sources */,
|
||||
839D916C1EF3E20B0077C7C8 /* RNFirebaseAdMob.m in Sources */,
|
||||
8376F7161F7C149100D45A85 /* RNFirebaseFirestoreCollectionReference.m in Sources */,
|
||||
839D91761EF3E20B0077C7C8 /* RNFirebaseStorage.m in Sources */,
|
||||
8376F7151F7C149100D45A85 /* RNFirebaseFirestore.m in Sources */,
|
||||
839D91701EF3E20B0077C7C8 /* RNFirebaseAuth.m in Sources */,
|
||||
8323CF091F6FBD870071420B /* RNFirebaseAdMobNativeExpressManager.m in Sources */,
|
||||
8376F7141F7C149100D45A85 /* RNFirebaseFirestoreDocumentReference.m in Sources */,
|
||||
839D916F1EF3E20B0077C7C8 /* RNFirebaseAnalytics.m in Sources */,
|
||||
839D91711EF3E20B0077C7C8 /* RNFirebaseRemoteConfig.m in Sources */,
|
||||
D950369E1D19C77400F7094D /* RNFirebase.m in Sources */,
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef RNFirebaseFirestore_h
|
||||
#define RNFirebaseFirestore_h
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if __has_include(<Firestore/FIRFirestore.h>)
|
||||
|
||||
#import <Firestore/FIRFirestore.h>
|
||||
#import <React/RCTBridgeModule.h>
|
||||
#import <React/RCTEventEmitter.h>
|
||||
|
||||
@interface RNFirebaseFirestore : RCTEventEmitter <RCTBridgeModule> {}
|
||||
|
||||
+ (void)promiseRejectException:(RCTPromiseRejectBlock)reject error:(NSError *)error;
|
||||
|
||||
+ (FIRFirestore *)getFirestoreForApp:(NSString *)appName;
|
||||
|
||||
@end
|
||||
|
||||
#else
|
||||
@interface RNFirebaseFirestore : NSObject
|
||||
@end
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
#import "RNFirebaseFirestore.h"
|
||||
|
||||
#if __has_include(<Firestore/FIRFirestore.h>)
|
||||
|
||||
#import <Firebase.h>
|
||||
#import "RNFirebaseEvents.h"
|
||||
#import "RNFirebaseFirestoreCollectionReference.h"
|
||||
#import "RNFirebaseFirestoreDocumentReference.h"
|
||||
|
||||
@implementation RNFirebaseFirestore
|
||||
RCT_EXPORT_MODULE();
|
||||
|
||||
- (id)init {
|
||||
self = [super init];
|
||||
if (self != nil) {
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(collectionGet:(NSString *) appName
|
||||
path:(NSString *) path
|
||||
filters:(NSArray *) filters
|
||||
orders:(NSArray *) orders
|
||||
options:(NSDictionary *) options
|
||||
resolver:(RCTPromiseResolveBlock) resolve
|
||||
rejecter:(RCTPromiseRejectBlock) reject) {
|
||||
[[self getCollectionForAppPath:appName path:path filters:filters orders:orders options:options] get:resolve rejecter:reject];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(documentBatch:(NSString *) appName
|
||||
writes:(NSArray *) writes
|
||||
commitOptions:(NSDictionary *) commitOptions
|
||||
resolver:(RCTPromiseResolveBlock) resolve
|
||||
rejecter:(RCTPromiseRejectBlock) reject) {
|
||||
FIRFirestore *firestore = [RNFirebaseFirestore getFirestoreForApp:appName];
|
||||
FIRWriteBatch *batch = [firestore batch];
|
||||
|
||||
for (NSDictionary *write in writes) {
|
||||
NSString *type = write[@"type"];
|
||||
NSString *path = write[@"path"];
|
||||
NSDictionary *data = write[@"data"];
|
||||
|
||||
FIRDocumentReference *ref = [firestore documentWithPath:path];
|
||||
|
||||
if ([type isEqualToString:@"DELETE"]) {
|
||||
batch = [batch deleteDocument:ref];
|
||||
} else if ([type isEqualToString:@"SET"]) {
|
||||
NSDictionary *options = write[@"options"];
|
||||
if (options && options[@"merge"]) {
|
||||
batch = [batch setData:data forDocument:ref options:[FIRSetOptions merge]];
|
||||
} else {
|
||||
batch = [batch setData:data forDocument:ref];
|
||||
}
|
||||
} else if ([type isEqualToString:@"UPDATE"]) {
|
||||
batch = [batch updateData:data forDocument:ref];
|
||||
}
|
||||
}
|
||||
|
||||
[batch commitWithCompletion:^(NSError * _Nullable error) {
|
||||
if (error) {
|
||||
[RNFirebaseFirestore promiseRejectException:reject error:error];
|
||||
} else {
|
||||
NSMutableArray *result = [[NSMutableArray alloc] init];
|
||||
for (NSDictionary *write in writes) {
|
||||
// Missing fields from web SDK
|
||||
// writeTime
|
||||
[result addObject:@{}];
|
||||
}
|
||||
resolve(result);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(documentCollections:(NSString *) appName
|
||||
path:(NSString *) path
|
||||
resolver:(RCTPromiseResolveBlock) resolve
|
||||
rejecter:(RCTPromiseRejectBlock) reject) {
|
||||
[[self getDocumentForAppPath:appName path:path] get:resolve rejecter:reject];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(documentCreate:(NSString *) appName
|
||||
path:(NSString *) path
|
||||
data:(NSDictionary *) data
|
||||
resolver:(RCTPromiseResolveBlock) resolve
|
||||
rejecter:(RCTPromiseRejectBlock) reject) {
|
||||
[[self getDocumentForAppPath:appName path:path] create:data resolver:resolve rejecter:reject];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(documentDelete:(NSString *) appName
|
||||
path:(NSString *) path
|
||||
options:(NSDictionary *) options
|
||||
resolver:(RCTPromiseResolveBlock) resolve
|
||||
rejecter:(RCTPromiseRejectBlock) reject) {
|
||||
[[self getDocumentForAppPath:appName path:path] delete:options resolver:resolve rejecter:reject];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(documentGet:(NSString *) appName
|
||||
path:(NSString *) path
|
||||
resolver:(RCTPromiseResolveBlock) resolve
|
||||
rejecter:(RCTPromiseRejectBlock) reject) {
|
||||
[[self getDocumentForAppPath:appName path:path] get:resolve rejecter:reject];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(documentGetAll:(NSString *) appName
|
||||
documents:(NSString *) documents
|
||||
resolver:(RCTPromiseResolveBlock) resolve
|
||||
rejecter:(RCTPromiseRejectBlock) reject) {
|
||||
// Not supported on iOS out of the box
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(documentSet:(NSString *) appName
|
||||
path:(NSString *) path
|
||||
data:(NSDictionary *) data
|
||||
options:(NSDictionary *) options
|
||||
resolver:(RCTPromiseResolveBlock) resolve
|
||||
rejecter:(RCTPromiseRejectBlock) reject) {
|
||||
[[self getDocumentForAppPath:appName path:path] set:data options:options resolver:resolve rejecter:reject];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(documentUpdate:(NSString *) appName
|
||||
path:(NSString *) path
|
||||
data:(NSDictionary *) data
|
||||
resolver:(RCTPromiseResolveBlock) resolve
|
||||
rejecter:(RCTPromiseRejectBlock) reject) {
|
||||
[[self getDocumentForAppPath:appName path:path] update:data resolver:resolve rejecter:reject];
|
||||
}
|
||||
|
||||
/*
|
||||
* INTERNALS/UTILS
|
||||
*/
|
||||
+ (void)promiseRejectException:(RCTPromiseRejectBlock)reject error:(NSError *)error {
|
||||
// TODO
|
||||
// NSDictionary *jsError = [RNFirebaseDatabase getJSError:databaseError];
|
||||
// reject([jsError valueForKey:@"code"], [jsError valueForKey:@"message"], databaseError);
|
||||
reject(@"TODO", [error description], error);
|
||||
}
|
||||
|
||||
+ (FIRFirestore *)getFirestoreForApp:(NSString *)appName {
|
||||
FIRApp *app = [FIRApp appNamed:appName];
|
||||
return [FIRFirestore firestoreForApp:app];
|
||||
}
|
||||
|
||||
- (RNFirebaseFirestoreCollectionReference *)getCollectionForAppPath:(NSString *)appName path:(NSString *)path filters:(NSArray *)filters orders:(NSArray *)orders options:(NSDictionary *)options {
|
||||
return [[RNFirebaseFirestoreCollectionReference alloc] initWithPathAndModifiers:appName path:path filters:filters orders:orders options:options];
|
||||
}
|
||||
|
||||
- (RNFirebaseFirestoreDocumentReference *)getDocumentForAppPath:(NSString *)appName path:(NSString *)path {
|
||||
return [[RNFirebaseFirestoreDocumentReference alloc] initWithPath:appName path:path];
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)supportedEvents {
|
||||
return @[DATABASE_SYNC_EVENT, DATABASE_TRANSACTION_EVENT];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#else
|
||||
@implementation RNFirebaseFirestore
|
||||
@end
|
||||
#endif
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef RNFirebaseFirestoreCollectionReference_h
|
||||
#define RNFirebaseFirestoreCollectionReference_h
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if __has_include(<Firestore/FIRFirestore.h>)
|
||||
|
||||
#import <Firestore/Firestore.h>
|
||||
#import "RNFirebaseFirestore.h"
|
||||
#import "RNFirebaseFirestoreDocumentReference.h"
|
||||
|
||||
@interface RNFirebaseFirestoreCollectionReference : NSObject
|
||||
@property NSString *app;
|
||||
@property NSString *path;
|
||||
@property NSArray *filters;
|
||||
@property NSArray *orders;
|
||||
@property NSDictionary *options;
|
||||
@property FIRQuery *query;
|
||||
|
||||
- (id)initWithPathAndModifiers:(NSString *)app path:(NSString *)path filters:(NSArray *)filters orders:(NSArray *)orders options:(NSDictionary *)options;
|
||||
- (void)get:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject;
|
||||
+ (NSDictionary *)snapshotToDictionary:(FIRQuerySnapshot *)querySnapshot;
|
||||
@end
|
||||
|
||||
#else
|
||||
|
||||
@interface RNFirebaseFirestoreCollectionReference : NSObject
|
||||
@end
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,145 @@
|
|||
#import "RNFirebaseFirestoreCollectionReference.h"
|
||||
|
||||
@implementation RNFirebaseFirestoreCollectionReference
|
||||
|
||||
#if __has_include(<Firestore/FIRFirestore.h>)
|
||||
|
||||
- (id)initWithPathAndModifiers:(NSString *) app
|
||||
path:(NSString *) path
|
||||
filters:(NSArray *) filters
|
||||
orders:(NSArray *) orders
|
||||
options:(NSDictionary *) options {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_app = app;
|
||||
_path = path;
|
||||
_filters = filters;
|
||||
_orders = orders;
|
||||
_options = options;
|
||||
_query = [self buildQuery];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)get:(RCTPromiseResolveBlock) resolve
|
||||
rejecter:(RCTPromiseRejectBlock) reject {
|
||||
[_query getDocumentsWithCompletion:^(FIRQuerySnapshot * _Nullable snapshot, NSError * _Nullable error) {
|
||||
if (error) {
|
||||
[RNFirebaseFirestore promiseRejectException:reject error:error];
|
||||
} else {
|
||||
NSDictionary *data = [RNFirebaseFirestoreCollectionReference snapshotToDictionary:snapshot];
|
||||
resolve(data);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (FIRQuery *)buildQuery {
|
||||
FIRQuery *query = (FIRQuery*)[[RNFirebaseFirestore getFirestoreForApp:_app] collectionWithPath:_path];
|
||||
query = [self applyFilters:query];
|
||||
query = [self applyOrders:query];
|
||||
query = [self applyOptions:query];
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
- (FIRQuery *)applyFilters:(FIRQuery *) query {
|
||||
for (NSDictionary *filter in _filters) {
|
||||
NSString *fieldPath = filter[@"fieldPath"];
|
||||
NSString *operator = filter[@"operator"];
|
||||
// TODO: Validate this works
|
||||
id value = filter[@"value"];
|
||||
|
||||
if ([operator isEqualToString:@"EQUAL"]) {
|
||||
query = [query queryWhereField:fieldPath isEqualTo:value];
|
||||
} else if ([operator isEqualToString:@"GREATER_THAN"]) {
|
||||
query = [query queryWhereField:fieldPath isGreaterThan:value];
|
||||
} else if ([operator isEqualToString:@"GREATER_THAN_OR_EQUAL"]) {
|
||||
query = [query queryWhereField:fieldPath isGreaterThanOrEqualTo:value];
|
||||
} else if ([operator isEqualToString:@"LESS_THAN"]) {
|
||||
query = [query queryWhereField:fieldPath isLessThan:value];
|
||||
} else if ([operator isEqualToString:@"LESS_THAN_OR_EQUAL"]) {
|
||||
query = [query queryWhereField:fieldPath isLessThanOrEqualTo:value];
|
||||
}
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
- (FIRQuery *)applyOrders:(FIRQuery *) query {
|
||||
for (NSDictionary *order in _orders) {
|
||||
NSString *direction = order[@"direction"];
|
||||
NSString *fieldPath = order[@"fieldPath"];
|
||||
|
||||
query = [query queryOrderedByField:fieldPath descending:([direction isEqualToString:@"DESCENDING"])];
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
- (FIRQuery *)applyOptions:(FIRQuery *) query {
|
||||
if (_options[@"endAt"]) {
|
||||
query = [query queryEndingAtValues:_options[@"endAt"]];
|
||||
}
|
||||
if (_options[@"endBefore"]) {
|
||||
query = [query queryEndingBeforeValues:_options[@"endBefore"]];
|
||||
}
|
||||
if (_options[@"offset"]) {
|
||||
// iOS doesn't support offset
|
||||
}
|
||||
if (_options[@"selectFields"]) {
|
||||
// iOS doesn't support selectFields
|
||||
}
|
||||
if (_options[@"startAfter"]) {
|
||||
query = [query queryStartingAfterValues:_options[@"startAfter"]];
|
||||
}
|
||||
if (_options[@"startAt"]) {
|
||||
query = [query queryStartingAtValues:_options[@"startAt"]];
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
+ (NSDictionary *)snapshotToDictionary:(FIRQuerySnapshot *)querySnapshot {
|
||||
NSMutableDictionary *snapshot = [[NSMutableDictionary alloc] init];
|
||||
[snapshot setValue:[self documentChangesToArray:querySnapshot.documentChanges] forKey:@"changes"];
|
||||
[snapshot setValue:[self documentSnapshotsToArray:querySnapshot.documents] forKey:@"documents"];
|
||||
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
+ (NSArray *)documentChangesToArray:(NSArray<FIRDocumentChange *> *) documentChanges {
|
||||
NSMutableArray *changes = [[NSMutableArray alloc] init];
|
||||
for (FIRDocumentChange *change in documentChanges) {
|
||||
[changes addObject:[self documentChangeToDictionary:change]];
|
||||
}
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
+ (NSDictionary *)documentChangeToDictionary:(FIRDocumentChange *)documentChange {
|
||||
NSMutableDictionary *change = [[NSMutableDictionary alloc] init];
|
||||
[change setValue:[RNFirebaseFirestoreDocumentReference snapshotToDictionary:documentChange.document] forKey:@"document"];
|
||||
[change setValue:@(documentChange.newIndex) forKey:@"newIndex"];
|
||||
[change setValue:@(documentChange.oldIndex) forKey:@"oldIndex"];
|
||||
|
||||
if (documentChange.type == FIRDocumentChangeTypeAdded) {
|
||||
[change setValue:@"added" forKey:@"type"];
|
||||
} else if (documentChange.type == FIRDocumentChangeTypeRemoved) {
|
||||
[change setValue:@"removed" forKey:@"type"];
|
||||
} else if (documentChange.type == FIRDocumentChangeTypeModified) {
|
||||
[change setValue:@"modified" forKey:@"type"];
|
||||
}
|
||||
|
||||
return change;
|
||||
}
|
||||
|
||||
+ (NSArray *)documentSnapshotsToArray:(NSArray<FIRDocumentSnapshot *> *) documentSnapshots {
|
||||
NSMutableArray *snapshots = [[NSMutableArray alloc] init];
|
||||
for (FIRDocumentSnapshot *snapshot in documentSnapshots) {
|
||||
[snapshots addObject:[RNFirebaseFirestoreDocumentReference snapshotToDictionary:snapshot]];
|
||||
}
|
||||
|
||||
return snapshots;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
#ifndef RNFirebaseFirestoreDocumentReference_h
|
||||
#define RNFirebaseFirestoreDocumentReference_h
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#if __has_include(<Firestore/FIRFirestore.h>)
|
||||
|
||||
#import <Firestore/Firestore.h>
|
||||
#import "RNFirebaseFirestore.h"
|
||||
|
||||
@interface RNFirebaseFirestoreDocumentReference : NSObject
|
||||
@property NSString *app;
|
||||
@property NSString *path;
|
||||
@property FIRDocumentReference *ref;
|
||||
|
||||
- (id)initWithPath:(NSString *)app path:(NSString *)path;
|
||||
- (void)collections:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject;
|
||||
- (void)create:(NSDictionary *)data resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject;
|
||||
- (void)delete:(NSDictionary *)options resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject;
|
||||
- (void)get:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject;
|
||||
- (void)set:(NSDictionary *)data options:(NSDictionary *)options resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject;
|
||||
- (void)update:(NSDictionary *)data resolver:(RCTPromiseResolveBlock) resolve rejecter:(RCTPromiseRejectBlock) reject;
|
||||
+ (NSDictionary *)snapshotToDictionary:(FIRDocumentSnapshot *)documentSnapshot;
|
||||
@end
|
||||
|
||||
#else
|
||||
|
||||
@interface RNFirebaseFirestoreDocumentReference : NSObject
|
||||
@end
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -0,0 +1,100 @@
|
|||
#import "RNFirebaseFirestoreDocumentReference.h"
|
||||
|
||||
@implementation RNFirebaseFirestoreDocumentReference
|
||||
|
||||
#if __has_include(<Firestore/FIRFirestore.h>)
|
||||
|
||||
- (id)initWithPath:(NSString *) app
|
||||
path:(NSString *) path {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
_app = app;
|
||||
_path = path;
|
||||
_ref = [[RNFirebaseFirestore getFirestoreForApp:_app] documentWithPath:_path];
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
- (void)delete:(NSDictionary *)options
|
||||
resolver:(RCTPromiseResolveBlock) resolve
|
||||
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);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (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];
|
||||
}];
|
||||
}
|
||||
|
||||
+ (void)handleWriteResponse:(NSError *) error
|
||||
resolver:(RCTPromiseResolveBlock) resolve
|
||||
rejecter:(RCTPromiseRejectBlock) reject {
|
||||
if (error) {
|
||||
[RNFirebaseFirestore promiseRejectException:reject error:error];
|
||||
} else {
|
||||
// Missing fields from web SDK
|
||||
// writeTime
|
||||
resolve(@{});
|
||||
}
|
||||
}
|
||||
|
||||
+ (NSDictionary *)snapshotToDictionary:(FIRDocumentSnapshot *)documentSnapshot {
|
||||
NSMutableDictionary *snapshot = [[NSMutableDictionary alloc] init];
|
||||
[snapshot setValue:documentSnapshot.reference.path forKey:@"path"];
|
||||
[snapshot setValue:documentSnapshot.data forKey:@"data"];
|
||||
// Missing fields from web SDK
|
||||
// createTime
|
||||
// readTime
|
||||
// updateTime
|
||||
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
||||
|
|
@ -13,7 +13,6 @@ const DIRECTIONS = {
|
|||
DESC: 'DESCENDING',
|
||||
desc: 'DESCENDING',
|
||||
};
|
||||
const DOCUMENT_NAME_FIELD = '__name__';
|
||||
|
||||
const OPERATORS = {
|
||||
'=': 'EQUAL',
|
||||
|
|
|
@ -7,34 +7,34 @@
|
|||
<key>AD_UNIT_ID_FOR_INTERSTITIAL_TEST</key>
|
||||
<string>ca-app-pub-3940256099942544/4411468910</string>
|
||||
<key>CLIENT_ID</key>
|
||||
<string>305229645282-22imndi01abc2p6esgtu1i1m9mqrd0ib.apps.googleusercontent.com</string>
|
||||
<string>17067372085-h95lq6v2fbjdl2i1f6pl26iurah37i8p.apps.googleusercontent.com</string>
|
||||
<key>REVERSED_CLIENT_ID</key>
|
||||
<string>com.googleusercontent.apps.305229645282-22imndi01abc2p6esgtu1i1m9mqrd0ib</string>
|
||||
<string>com.googleusercontent.apps.17067372085-h95lq6v2fbjdl2i1f6pl26iurah37i8p</string>
|
||||
<key>API_KEY</key>
|
||||
<string>AIzaSyAcdVLG5dRzA1ck_fa_xd4Z0cY7cga7S5A</string>
|
||||
<string>AIzaSyC8ZEruBCvS_6woF8_l07ILy1eXaD6J4vQ</string>
|
||||
<key>GCM_SENDER_ID</key>
|
||||
<string>305229645282</string>
|
||||
<string>17067372085</string>
|
||||
<key>PLIST_VERSION</key>
|
||||
<string>1</string>
|
||||
<key>BUNDLE_ID</key>
|
||||
<string>com.invertase.ReactNativeFirebaseDemo</string>
|
||||
<key>PROJECT_ID</key>
|
||||
<string>rnfirebase-b9ad4</string>
|
||||
<string>rnfirebase</string>
|
||||
<key>STORAGE_BUCKET</key>
|
||||
<string>rnfirebase-b9ad4.appspot.com</string>
|
||||
<string>rnfirebase.appspot.com</string>
|
||||
<key>IS_ADS_ENABLED</key>
|
||||
<true/>
|
||||
<true></true>
|
||||
<key>IS_ANALYTICS_ENABLED</key>
|
||||
<false/>
|
||||
<false></false>
|
||||
<key>IS_APPINVITE_ENABLED</key>
|
||||
<false/>
|
||||
<false></false>
|
||||
<key>IS_GCM_ENABLED</key>
|
||||
<true/>
|
||||
<true></true>
|
||||
<key>IS_SIGNIN_ENABLED</key>
|
||||
<true/>
|
||||
<true></true>
|
||||
<key>GOOGLE_APP_ID</key>
|
||||
<string>1:305229645282:ios:7b45748cb1117d2d</string>
|
||||
<string>1:17067372085:ios:7b45748cb1117d2d</string>
|
||||
<key>DATABASE_URL</key>
|
||||
<string>https://rnfirebase-b9ad4.firebaseio.com</string>
|
||||
<string>https://rnfirebase-5579a.firebaseio.com</string>
|
||||
</dict>
|
||||
</plist>
|
||||
</plist>
|
||||
|
|
|
@ -19,6 +19,7 @@ target 'ReactNativeFirebaseDemo' do
|
|||
pod 'Firebase/Crash'
|
||||
pod 'Firebase/Database'
|
||||
pod 'Firebase/DynamicLinks'
|
||||
pod 'Firestore', :podspec => 'https://storage.googleapis.com/firebase-preview-drop/ios/firestore/0.7.0/Firestore.podspec.json'
|
||||
pod 'Firebase/Messaging'
|
||||
pod 'Firebase/RemoteConfig'
|
||||
pod 'Firebase/Storage'
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
PODS:
|
||||
- BoringSSL (8.2):
|
||||
- BoringSSL/Implementation (= 8.2)
|
||||
- BoringSSL/Interface (= 8.2)
|
||||
- BoringSSL/Implementation (8.2):
|
||||
- BoringSSL/Interface (= 8.2)
|
||||
- BoringSSL/Interface (8.2)
|
||||
- Firebase/AdMob (4.1.0):
|
||||
- Firebase/Core
|
||||
- Google-Mobile-Ads-SDK (= 7.22.0)
|
||||
|
@ -77,6 +83,13 @@ PODS:
|
|||
- FirebaseAnalytics (~> 4.0)
|
||||
- FirebaseCore (~> 4.0)
|
||||
- GTMSessionFetcher/Core (~> 1.1)
|
||||
- Firestore (0.7.0):
|
||||
- FirebaseAnalytics (~> 4.0)
|
||||
- FirebaseAuth (~> 4.1)
|
||||
- FirebaseCore (~> 4.0)
|
||||
- gRPC-ProtoRPC (~> 1.0)
|
||||
- leveldb-library (~> 1.18)
|
||||
- Protobuf (~> 3.1)
|
||||
- Google-Mobile-Ads-SDK (7.22.0)
|
||||
- GoogleToolboxForMac/DebugUtils (2.1.1):
|
||||
- GoogleToolboxForMac/Defines (= 2.1.1)
|
||||
|
@ -90,6 +103,22 @@ PODS:
|
|||
- GoogleToolboxForMac/Defines (= 2.1.1)
|
||||
- GoogleToolboxForMac/NSString+URLArguments (= 2.1.1)
|
||||
- GoogleToolboxForMac/NSString+URLArguments (2.1.1)
|
||||
- gRPC (1.4.2):
|
||||
- gRPC-Core (= 1.4.2)
|
||||
- gRPC-RxLibrary (= 1.4.2)
|
||||
- gRPC-Core (1.4.2):
|
||||
- gRPC-Core/Implementation (= 1.4.2)
|
||||
- gRPC-Core/Interface (= 1.4.2)
|
||||
- gRPC-Core/Implementation (1.4.2):
|
||||
- BoringSSL (~> 8.0)
|
||||
- gRPC-Core/Interface (= 1.4.2)
|
||||
- nanopb (~> 0.3)
|
||||
- gRPC-Core/Interface (1.4.2)
|
||||
- gRPC-ProtoRPC (1.4.2):
|
||||
- gRPC (= 1.4.2)
|
||||
- gRPC-RxLibrary (= 1.4.2)
|
||||
- Protobuf (~> 3.0)
|
||||
- gRPC-RxLibrary (1.4.2)
|
||||
- GTMSessionFetcher/Core (1.1.11)
|
||||
- leveldb-library (1.18.3)
|
||||
- nanopb (0.3.8):
|
||||
|
@ -121,11 +150,14 @@ DEPENDENCIES:
|
|||
- Firebase/Performance
|
||||
- Firebase/RemoteConfig
|
||||
- Firebase/Storage
|
||||
- Firestore (from `https://storage.googleapis.com/firebase-preview-drop/ios/firestore/0.7.0/Firestore.podspec.json`)
|
||||
- React (from `../node_modules/react-native`)
|
||||
- RNFirebase (from `./../../`)
|
||||
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
Firestore:
|
||||
:podspec: https://storage.googleapis.com/firebase-preview-drop/ios/firestore/0.7.0/Firestore.podspec.json
|
||||
React:
|
||||
:path: "../node_modules/react-native"
|
||||
RNFirebase:
|
||||
|
@ -134,6 +166,7 @@ EXTERNAL SOURCES:
|
|||
:path: "../node_modules/react-native/ReactCommon/yoga"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
BoringSSL: 4135ae556ee2b82ee85477c39ba917a3dd5424ba
|
||||
Firebase: ebebf41db7f10e0c7668b6eaaa857fbe599aa478
|
||||
FirebaseAnalytics: 76f754d37ca5b04f36856729b6af3ca0152d1069
|
||||
FirebaseAuth: 8d1d2389cf82f891048d6d50d27d044f55ae09a6
|
||||
|
@ -146,8 +179,13 @@ SPEC CHECKSUMS:
|
|||
FirebasePerformance: 36bdb0500213b459ae991766801d5dc5399ff231
|
||||
FirebaseRemoteConfig: 5b3e3301ef2f237b1b588e8ef3211b5a22e9e15d
|
||||
FirebaseStorage: 661fc1f8d4131891d256b62e82a45ace8b3f0c3b
|
||||
Firestore: 80f352a0b5260500b11d7e4626b81a19d4eba312
|
||||
Google-Mobile-Ads-SDK: 1bdf1a4244d0553b1840239874c209c01aef055f
|
||||
GoogleToolboxForMac: 8e329f1b599f2512c6b10676d45736bcc2cbbeb0
|
||||
gRPC: 74b57d3c8a9366e09493828e0a1d27f6d69a79fd
|
||||
gRPC-Core: 642d29e59e5490374622b0629c2dd1c4c111775c
|
||||
gRPC-ProtoRPC: 675ef3d484c06967ed2a5f5ee0e510a3756f755e
|
||||
gRPC-RxLibrary: 7a25c5c25282669a82d1783d7e8a036f53e8ef27
|
||||
GTMSessionFetcher: 5ad62e8200fa00ed011fe5e08d27fef72c5b1429
|
||||
leveldb-library: 10fb39c39e243db4af1828441162405bbcec1404
|
||||
nanopb: 5601e6bca2dbf1ed831b519092ec110f66982ca3
|
||||
|
@ -156,6 +194,6 @@ SPEC CHECKSUMS:
|
|||
RNFirebase: 60be8c01b94551a12e7be5431189e8ee8cefcdd3
|
||||
Yoga: c90474ca3ec1edba44c97b6c381f03e222a9e287
|
||||
|
||||
PODFILE CHECKSUM: 46b6a553f3c9fd264b449806b373d33b4af518b5
|
||||
PODFILE CHECKSUM: 49e66d8a1599e426396a3ba88a24baacc7f5423c
|
||||
|
||||
COCOAPODS: 1.2.1
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
import React, { Component } from 'react';
|
||||
import { Text, View } from 'react-native';
|
||||
import fb from './firebase';
|
||||
|
||||
global.Promise = require('bluebird');
|
||||
|
||||
const firebase = fb.native;
|
||||
|
||||
|
||||
function bootstrap() {
|
||||
// Remove logging on production
|
||||
if (!__DEV__) {
|
||||
console.log = () => {
|
||||
};
|
||||
console.warn = () => {
|
||||
};
|
||||
console.error = () => {
|
||||
};
|
||||
console.disableYellowBox = true;
|
||||
}
|
||||
|
||||
class Root extends Component {
|
||||
|
||||
async componentDidMount() {
|
||||
console.log(`Starting`);
|
||||
const db = firebase.firestore();
|
||||
const docRef = await db.collection('chris').add({ first: 'Ada', last: 'Lovelace', born: 1815 });
|
||||
console.log(`Document written with ID: ${docRef.id}`);
|
||||
const docRef2 = await db.collection('chris').add({ first: 'Alan', middle: 'Mathison', last: 'Turing', born: 1912 });
|
||||
console.log(`Document written with ID: ${docRef2.id}`);
|
||||
await db.collection('chris').doc('manual').set({ first: 'Manual', last: 'Man', born: 1234 });
|
||||
console.log('Manual document set');
|
||||
await db.collection('chris').doc().set({ first: 'Auto', last: 'Man', born: 2000 });
|
||||
console.log('Auto document set');
|
||||
|
||||
const docRefT = db.doc(docRef.path);
|
||||
const docRefS = await docRefT.get();
|
||||
console.log(`Should be the same as first written ID: ${docRefT.id}`, docRefS.data());
|
||||
|
||||
await docRefT.set({ empty: true });
|
||||
const docRefS2 = await docRefT.get();
|
||||
console.log(`Should have empty only: ${docRefT.id}`, docRefS2.data());
|
||||
|
||||
await docRefT.set({ first: 'Ada', last: 'Lovelace', born: 1815 }, { merge: true });
|
||||
const docRefS3 = await docRefT.get();
|
||||
console.log(`Should have everything plus empty: ${docRefT.id}`, docRefS3.data());
|
||||
|
||||
await docRefT.update({ first: 'AdaUpdated' });
|
||||
const docRefS4 = await docRefT.get();
|
||||
console.log(`Should have updated firstname: ${docRefT.id}`, docRefS4.data());
|
||||
|
||||
const docs = await db.collection('chris').get();
|
||||
const tasks = [];
|
||||
docs.forEach((doc) => {
|
||||
console.log(`Cleaning up ${doc.id}`, doc.data());
|
||||
tasks.push(doc.ref.delete());
|
||||
});
|
||||
Promise.all(tasks);
|
||||
console.log('Finished cleaning collection');
|
||||
|
||||
const nycRef = db.collection('chris').doc('NYC');
|
||||
const sfRef = db.collection('chris').doc('SF');
|
||||
|
||||
await db.batch()
|
||||
.set(nycRef, { name: 'New York City' })
|
||||
.set(sfRef, { name: 'San Francisco' })
|
||||
.commit();
|
||||
|
||||
const docs2 = await db.collection('chris').get();
|
||||
docs2.forEach((doc) => {
|
||||
console.log(`Got ${doc.id}`, doc.data());
|
||||
});
|
||||
|
||||
await db.batch()
|
||||
.update(nycRef, { population: 1000000 })
|
||||
.update(sfRef, { name: 'San Fran' })
|
||||
.commit();
|
||||
const docs3 = await db.collection('chris').get();
|
||||
docs3.forEach((doc) => {
|
||||
console.log(`Got ${doc.id}`, doc.data());
|
||||
});
|
||||
|
||||
await db.batch()
|
||||
.delete(nycRef)
|
||||
.delete(sfRef)
|
||||
.commit();
|
||||
const docs4 = await db.collection('chris').get();
|
||||
docs4.forEach((doc) => {
|
||||
console.log(`Got ${doc.id}`, doc.data());
|
||||
});
|
||||
console.log('Finished');
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View>
|
||||
<Text>Check console logs</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return Root;
|
||||
}
|
||||
|
||||
export default bootstrap();
|
Loading…
Reference in New Issue