From 2ca05eeb982da44ed6f38a9efbf1b6476a47523e Mon Sep 17 00:00:00 2001 From: Douglas Alves Date: Sun, 24 Nov 2024 07:31:23 -0300 Subject: [PATCH 1/2] New Android array serialization --- android/build.gradle | 2 +- android/manifest | 2 +- .../TitaniumFirebaseFirestoreModule.kt | 82 ++- ios/Classes/FirebaseFirestoreModule.m | 474 +++++++++--------- ios/manifest | 2 +- 5 files changed, 319 insertions(+), 243 deletions(-) diff --git a/android/build.gradle b/android/build.gradle index 83c33e8..7d35fa2 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -4,5 +4,5 @@ repositories { } dependencies { - implementation 'com.google.firebase:firebase-firestore-ktx:24.3.1' + implementation 'com.google.firebase:firebase-firestore-ktx:25.1.1' } diff --git a/android/manifest b/android/manifest index 4ad9fa9..2130202 100644 --- a/android/manifest +++ b/android/manifest @@ -2,7 +2,7 @@ # this is your module manifest and used by Titanium # during compilation, packaging, distribution, etc. # -version: 2.0.0 +version: 2.0.2 apiversion: 4 architectures: arm64-v8a armeabi-v7a x86 x86_64 description: titanium-firebase-firestore diff --git a/android/src/firebase/firestore/TitaniumFirebaseFirestoreModule.kt b/android/src/firebase/firestore/TitaniumFirebaseFirestoreModule.kt index 99af2a3..7140cad 100644 --- a/android/src/firebase/firestore/TitaniumFirebaseFirestoreModule.kt +++ b/android/src/firebase/firestore/TitaniumFirebaseFirestoreModule.kt @@ -9,6 +9,8 @@ package firebase.firestore +import android.util.Log +import com.google.firebase.firestore.FirebaseFirestoreException import com.google.firebase.firestore.ktx.firestore import com.google.firebase.ktx.Firebase import org.appcelerator.kroll.KrollDict @@ -20,7 +22,49 @@ import org.appcelerator.kroll.annotations.Kroll @Kroll.module(name = "TitaniumFirebaseFirestore", id = "firebase.firestore") class TitaniumFirebaseFirestoreModule: KrollModule() { + private fun convertToFirestoreMap(input: KrollDict): Map { + val output = mutableMapOf() + input.keys.forEach { key -> + val value = input[key] + when (value) { + is KrollDict -> output[key] = convertToFirestoreMap(value) // Substituir objetos aninhados + is Array<*> -> output[key] = value.toList() // Converter array para List + is List<*> -> output[key] = value // Já é uma lista compatível + else -> output[key] = value // Outros tipos são mantidos + } + } + return output + } + // Methods + @Kroll.method + fun addDocumentWithId(params: KrollDict) { + val callback = params["callback"] as KrollFunction + val collection = params["collection"] as String + val customDocumentId = params["id"] as String + val data = params.getKrollDict("data") + + // Converte KrollDict para Map compatível com Firestore + val firestoreData = convertToFirestoreMap(data) + + Firebase.firestore.collection(collection) + .document(customDocumentId) + .set(firestoreData) + .addOnSuccessListener { + val event = KrollDict() + event["success"] = true + event["documentID"] = customDocumentId + + callback.callAsync(getKrollObject(), event) + } + .addOnFailureListener { error -> + val event = KrollDict() + event["success"] = false + event["error"] = error.localizedMessage + + callback.callAsync(getKrollObject(), event) + } + } @Kroll.method fun addDocument(params: KrollDict) { @@ -28,8 +72,11 @@ class TitaniumFirebaseFirestoreModule: KrollModule() { val collection = params["collection"] as String val data = params.getKrollDict("data") + // Converte KrollDict para Map compatível com Firestore + val firestoreData = convertToFirestoreMap(data) + Firebase.firestore.collection(collection) - .add(data) + .add(firestoreData) .addOnSuccessListener { val event = KrollDict() event["success"] = true @@ -77,6 +124,33 @@ class TitaniumFirebaseFirestoreModule: KrollModule() { } } + @Kroll.method + fun updateOneFieldInDocument(params: KrollDict) { + val callback = params["callback"] as KrollFunction + val collection = params["collection"] as String + val fieldName = params["field_name"] as String + val fieldValue = params["field_value"] + val document = params["document"] as String + + Firebase.firestore.collection(collection) + .document(document) + .update(fieldName, fieldValue) + .addOnSuccessListener { + val event = KrollDict() + event["success"] = true + event["field"] = fieldName + event["value"] = fieldValue + callback.callAsync(getKrollObject(), event) + } + .addOnFailureListener { error -> + val event = KrollDict() + event["success"] = false + event["error"] = error.localizedMessage + + callback.callAsync(getKrollObject(), event) + } + } + @Kroll.method fun updateDocument(params: KrollDict) { val callback = params["callback"] as KrollFunction @@ -84,13 +158,15 @@ class TitaniumFirebaseFirestoreModule: KrollModule() { val data = params.getKrollDict("data") val document = params["document"] as String + // Converte KrollDict para Map compatível com Firestore + val firestoreData = convertToFirestoreMap(data) + Firebase.firestore.collection(collection) .document(document) - .update(data) + .set(firestoreData) .addOnSuccessListener { val event = KrollDict() event["success"] = true - callback.callAsync(getKrollObject(), event) } .addOnFailureListener { error -> diff --git a/ios/Classes/FirebaseFirestoreModule.m b/ios/Classes/FirebaseFirestoreModule.m index 803f70f..3892ece 100644 --- a/ios/Classes/FirebaseFirestoreModule.m +++ b/ios/Classes/FirebaseFirestoreModule.m @@ -1,256 +1,256 @@ -/** - * titanium-firebase-firestore - * - * Created by Hans Knöchel - */ - -#import "FirebaseFirestoreModule.h" -#import "TiBase.h" -#import "TiFirestoreUtils.h" -#import "TiHost.h" -#import "TiUtils.h" - -#import - -@implementation FirebaseFirestoreModule - -#pragma mark Internal - -- (id)moduleGUID -{ - return @"01ba870c-6842-4b23-a8db-eb1eaffebf3f"; -} - -- (NSString *)moduleId -{ - return @"firebase.firestore"; -} - -- (void)addDocument:(id)params -{ - ENSURE_SINGLE_ARG(params, NSDictionary); - - KrollCallback *callback = params[@"callback"]; - NSString *collection = params[@"collection"]; - NSDictionary *data = params[@"data"]; // TODO: Parse "FIRFieldValue" proxy types - - __block FIRDocumentReference *ref = [[FIRFirestore.firestore collectionWithPath:collection] addDocumentWithData:data - completion:^(NSError *_Nullable error) { - if (error != nil) { - [callback call:@[ @{@"success" : @(NO), - @"error" : error.localizedDescription} ] - thisObject:self]; - return; - } - - [callback call:@[ @{@"success" : @(YES), - @"documentID" : NULL_IF_NIL(ref.documentID), - @"documentPath" : NULL_IF_NIL(ref.path)} ] - thisObject:self]; - }]; -} - -- (void)queryDocuments:(id)params -{ - ENSURE_SINGLE_ARG(params, NSDictionary); - KrollCallback *callback = params[@"callback"]; - NSString *collection = params[@"collection"]; - NSString *document = params[@"document"]; - - FIRCollectionReference *ref = [FIRFirestore.firestore collectionWithPath:collection]; - FIRDocumentReference *documentReference = [[FIRFirestore.firestore collectionWithPath:collection] documentWithPath:document]; - FIRQuery *query = [FIRFirestore.firestore collectionWithPath:params[@"path"]]; - - NSDictionary *parameters = params[@"parameters"]; - NSArray *whereConditions = params[@"where"]; - - for (id item in whereConditions) { - NSArray *condition = item; - NSString *fieldName = condition[0]; - NSString *op = condition[1]; - id value = condition[2]; - if ([op isEqualToString:@"=="]) { - query = [query queryWhereField:fieldName isEqualTo:value]; - } else if ([op isEqualToString:@"<"]) { - query = [query queryWhereField:fieldName isLessThan:value]; - } else if ([op isEqualToString:@"<="]) { - query = [query queryWhereField:fieldName isLessThanOrEqualTo:value]; - } else if ([op isEqualToString:@">"]) { - query = [query queryWhereField:fieldName isGreaterThan:value]; - } else if ([op isEqualToString:@">="]) { - query = [query queryWhereField:fieldName isGreaterThanOrEqualTo:value]; - } else if ([op isEqualToString:@"array-contains"]) { - query = [query queryWhereField:fieldName arrayContains:value]; - } else { - NSLog(@"[ERROR] Unhandled operator \"%@\" on field \"%@\"", op, fieldName); - // Unsupported operator + /** + * titanium-firebase-firestore + * + * Created by Hans Knöchel + */ + + #import "FirebaseFirestoreModule.h" + #import "TiBase.h" + #import "TiFirestoreUtils.h" + #import "TiHost.h" + #import "TiUtils.h" + + #import + + @implementation FirebaseFirestoreModule + + #pragma mark Internal + + - (id)moduleGUID + { + return @"01ba870c-6842-4b23-a8db-eb1eaffebf3f"; } - } - - id limit = parameters[@"limit"]; - if (limit) { - NSNumber *length = limit; - query = [query queryLimitedTo:[length intValue]]; - } - - NSArray *orderBy = parameters[@"orderBy"]; - if (orderBy) { - for (id item in orderBy) { - NSArray *orderByParameters = item; - NSString *fieldName = orderByParameters[0]; - NSNumber *descending = orderByParameters[1]; - query = [query queryOrderedByField:fieldName descending:[descending boolValue]]; + + - (NSString *)moduleId + { + return @"firebase.firestore"; } - } - - id startAt = parameters[@"startAt"]; - if (startAt) { - NSArray *startAtValues = startAt; - query = [query queryStartingAtValues:startAtValues]; - } - - id startAfter = parameters[@"startAfter"]; - if (startAfter) { - NSArray *startAfterValues = startAfter; - query = [query queryStartingAfterValues:startAfterValues]; - } - - id endAt = parameters[@"endAt"]; - if (endAt) { - NSArray *endAtValues = endAt; - query = [query queryEndingAtValues:endAtValues]; - } - - id endBefore = parameters[@"endBefore"]; - if (endBefore) { - NSArray *endBeforeValues = endBefore; - query = [query queryEndingBeforeValues:endBeforeValues]; - } - - [query getDocumentsWithCompletion:^(FIRQuerySnapshot *_Nullable snapshot, NSError *_Nullable error) { - if (error != nil) { - [callback call:@[ @{ - @"success" : @(NO), - @"error" : error.localizedDescription - } ] - thisObject:self]; - return; + + - (void)addDocument:(id)params + { + ENSURE_SINGLE_ARG(params, NSDictionary); + + KrollCallback *callback = params[@"callback"]; + NSString *collection = params[@"collection"]; + NSDictionary *data = params[@"data"]; // TODO: Parse "FIRFieldValue" proxy types + + __block FIRDocumentReference *ref = [[FIRFirestore.firestore collectionWithPath:collection] addDocumentWithData:data + completion:^(NSError *_Nullable error) { + if (error != nil) { + [callback call:@[ @{@"success" : @(NO), + @"error" : error.localizedDescription} ] + thisObject:self]; + return; + } + + [callback call:@[ @{@"success" : @(YES), + @"documentID" : NULL_IF_NIL(ref.documentID), + @"documentPath" : NULL_IF_NIL(ref.path)} ] + thisObject:self]; + }]; } - NSMutableArray *> *documents = [NSMutableArray arrayWithCapacity:snapshot.documents.count]; - - // Map the documents to make sure it's a bridgeable type - [snapshot.documents enumerateObjectsUsingBlock:^(FIRQueryDocumentSnapshot *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) { - [documents addObject:[TiFirestoreUtils mappedFirestoreValue:obj.data]]; - }]; - [callback call:@[ @{ - @"success" : @(YES), - @"documents" : documents - } ] - thisObject:self]; - }]; -} - -- (void)getDocuments:(id)params -{ - ENSURE_SINGLE_ARG(params, NSDictionary); - - KrollCallback *callback = params[@"callback"]; - NSString *collection = params[@"collection"]; - - [[FIRFirestore.firestore collectionWithPath:collection] getDocumentsWithCompletion:^(FIRQuerySnapshot *_Nullable snapshot, NSError *_Nullable error) { - if (error != nil) { - [callback call:@[ @{@"success" : @(NO), - @"error" : error.localizedDescription} ] - thisObject:self]; - return; + - (void)queryDocuments:(id)params + { + ENSURE_SINGLE_ARG(params, NSDictionary); + KrollCallback *callback = params[@"callback"]; + NSString *collection = params[@"collection"]; + NSString *document = params[@"document"]; + + FIRCollectionReference *ref = [FIRFirestore.firestore collectionWithPath:collection]; + FIRDocumentReference *documentReference = [[FIRFirestore.firestore collectionWithPath:collection] documentWithPath:document]; + FIRQuery *query = [FIRFirestore.firestore collectionWithPath:params[@"path"]]; + + NSDictionary *parameters = params[@"parameters"]; + NSArray *whereConditions = params[@"where"]; + + for (id item in whereConditions) { + NSArray *condition = item; + NSString *fieldName = condition[0]; + NSString *op = condition[1]; + id value = condition[2]; + if ([op isEqualToString:@"=="]) { + query = [query queryWhereField:fieldName isEqualTo:value]; + } else if ([op isEqualToString:@"<"]) { + query = [query queryWhereField:fieldName isLessThan:value]; + } else if ([op isEqualToString:@"<="]) { + query = [query queryWhereField:fieldName isLessThanOrEqualTo:value]; + } else if ([op isEqualToString:@">"]) { + query = [query queryWhereField:fieldName isGreaterThan:value]; + } else if ([op isEqualToString:@">="]) { + query = [query queryWhereField:fieldName isGreaterThanOrEqualTo:value]; + } else if ([op isEqualToString:@"array-contains"]) { + query = [query queryWhereField:fieldName arrayContains:value]; + } else { + NSLog(@"[ERROR] Unhandled operator \"%@\" on field \"%@\"", op, fieldName); + // Unsupported operator + } + } + + id limit = parameters[@"limit"]; + if (limit) { + NSNumber *length = limit; + query = [query queryLimitedTo:[length intValue]]; + } + + NSArray *orderBy = parameters[@"orderBy"]; + if (orderBy) { + for (id item in orderBy) { + NSArray *orderByParameters = item; + NSString *fieldName = orderByParameters[0]; + NSNumber *descending = orderByParameters[1]; + query = [query queryOrderedByField:fieldName descending:[descending boolValue]]; + } + } + + id startAt = parameters[@"startAt"]; + if (startAt) { + NSArray *startAtValues = startAt; + query = [query queryStartingAtValues:startAtValues]; + } + + id startAfter = parameters[@"startAfter"]; + if (startAfter) { + NSArray *startAfterValues = startAfter; + query = [query queryStartingAfterValues:startAfterValues]; + } + + id endAt = parameters[@"endAt"]; + if (endAt) { + NSArray *endAtValues = endAt; + query = [query queryEndingAtValues:endAtValues]; + } + + id endBefore = parameters[@"endBefore"]; + if (endBefore) { + NSArray *endBeforeValues = endBefore; + query = [query queryEndingBeforeValues:endBeforeValues]; + } + + [query getDocumentsWithCompletion:^(FIRQuerySnapshot *_Nullable snapshot, NSError *_Nullable error) { + if (error != nil) { + [callback call:@[ @{ + @"success" : @(NO), + @"error" : error.localizedDescription + } ] + thisObject:self]; + return; + } + + NSMutableArray *> *documents = [NSMutableArray arrayWithCapacity:snapshot.documents.count]; + + // Map the documents to make sure it's a bridgeable type + [snapshot.documents enumerateObjectsUsingBlock:^(FIRQueryDocumentSnapshot *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) { + [documents addObject:[TiFirestoreUtils mappedFirestoreValue:obj.data]]; + }]; + [callback call:@[ @{ + @"success" : @(YES), + @"documents" : documents + } ] + thisObject:self]; + }]; } - NSMutableArray *> *documents = [NSMutableArray arrayWithCapacity:snapshot.documents.count]; + - (void)getDocuments:(id)params + { + ENSURE_SINGLE_ARG(params, NSDictionary); - [snapshot.documents enumerateObjectsUsingBlock:^(FIRQueryDocumentSnapshot *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) { - [documents addObject:[TiFirestoreUtils mappedFirestoreValue:obj.data]]; - }]; + KrollCallback *callback = params[@"callback"]; + NSString *collection = params[@"collection"]; - [callback call:@[ @{@"success" : @(YES), - @"documents" : documents} ] - thisObject:self]; - }]; -} + [[FIRFirestore.firestore collectionWithPath:collection] getDocumentsWithCompletion:^(FIRQuerySnapshot *_Nullable snapshot, NSError *_Nullable error) { + if (error != nil) { + [callback call:@[ @{@"success" : @(NO), + @"error" : error.localizedDescription} ] + thisObject:self]; + return; + } -- (void)getSingleDocument:(id)params -{ - ENSURE_SINGLE_ARG(params, NSDictionary); + NSMutableArray *> *documents = [NSMutableArray arrayWithCapacity:snapshot.documents.count]; - KrollCallback *callback = params[@"callback"]; - NSString *collection = params[@"collection"]; - NSString *document = params[@"document"]; + [snapshot.documents enumerateObjectsUsingBlock:^(FIRQueryDocumentSnapshot *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) { + [documents addObject:[TiFirestoreUtils mappedFirestoreValue:obj.data]]; + }]; - FIRDocumentReference *documentReference = [[FIRFirestore.firestore collectionWithPath:collection] documentWithPath:document]; + [callback call:@[ @{@"success" : @(YES), + @"documents" : documents} ] + thisObject:self]; + }]; + } + + - (void)getSingleDocument:(id)params + { + ENSURE_SINGLE_ARG(params, NSDictionary); + + KrollCallback *callback = params[@"callback"]; + NSString *collection = params[@"collection"]; + NSString *document = params[@"document"]; + + FIRDocumentReference *documentReference = [[FIRFirestore.firestore collectionWithPath:collection] documentWithPath:document]; - [documentReference getDocumentWithCompletion:^(FIRDocumentSnapshot *_Nullable snapshot, NSError *_Nullable error) { - if (error != nil) { - [callback call:@[ @{@"success" : @(NO), - @"error" : error.localizedDescription} ] - thisObject:self]; - return; + [documentReference getDocumentWithCompletion:^(FIRDocumentSnapshot *_Nullable snapshot, NSError *_Nullable error) { + if (error != nil) { + [callback call:@[ @{@"success" : @(NO), + @"error" : error.localizedDescription} ] + thisObject:self]; + return; + } + + [callback call:@[ @{@"success" : @(YES), + @"document" : [snapshot data]} ] + thisObject:self]; + }]; } - [callback call:@[ @{@"success" : @(YES), - @"document" : [snapshot data]} ] - thisObject:self]; - }]; -} - -- (void)updateDocument:(id)params -{ - ENSURE_SINGLE_ARG(params, NSDictionary); - - KrollCallback *callback = params[@"callback"]; - NSString *collection = params[@"collection"]; - NSDictionary *data = params[@"data"]; // TODO: Parse "FIRFieldValue" proxy types - NSString *document = params[@"document"]; - - [[[FIRFirestore.firestore collectionWithPath:collection] documentWithPath:document] updateData:data - completion:^(NSError *_Nullable error) { - if (error != nil) { - [callback call:@[ @{@"success" : @(NO), - @"error" : error.localizedDescription} ] - thisObject:self]; - return; - } - - [callback call:@[ @{@"success" : @(YES)} ] thisObject:self]; - }]; -} - -- (void)deleteDocument:(id)params -{ - ENSURE_SINGLE_ARG(params, NSDictionary); - - KrollCallback *callback = params[@"callback"]; - NSString *collection = params[@"collection"]; - NSDictionary *data = params[@"data"]; - NSString *document = params[@"document"]; - - [[[FIRFirestore.firestore collectionWithPath:collection] documentWithPath:document] deleteDocumentWithCompletion:^(NSError *_Nullable error) { - if (error != nil) { - [callback call:@[ @{@"success" : @(NO), - @"error" : error.localizedDescription} ] - thisObject:self]; - return; + - (void)updateDocument:(id)params + { + ENSURE_SINGLE_ARG(params, NSDictionary); + + KrollCallback *callback = params[@"callback"]; + NSString *collection = params[@"collection"]; + NSDictionary *data = params[@"data"]; // TODO: Parse "FIRFieldValue" proxy types + NSString *document = params[@"document"]; + + [[[FIRFirestore.firestore collectionWithPath:collection] documentWithPath:document] setData:data + completion:^(NSError * _Nullable error) { + if (error != nil) { + [callback call:@[ @{@"success" : @(NO), + @"error" : error.localizedDescription} ] + thisObject:self]; + return; + } + + [callback call:@[ @{@"success" : @(YES)} ] thisObject:self]; + }]; } - [callback call:@[ @{@"success" : @(YES)} ] thisObject:self]; - }]; -} + - (void)deleteDocument:(id)params + { + ENSURE_SINGLE_ARG(params, NSDictionary); + + KrollCallback *callback = params[@"callback"]; + NSString *collection = params[@"collection"]; + NSDictionary *data = params[@"data"]; + NSString *document = params[@"document"]; + + [[[FIRFirestore.firestore collectionWithPath:collection] documentWithPath:document] deleteDocumentWithCompletion:^(NSError *_Nullable error) { + if (error != nil) { + [callback call:@[ @{@"success" : @(NO), + @"error" : error.localizedDescription} ] + thisObject:self]; + return; + } + + [callback call:@[ @{@"success" : @(YES)} ] thisObject:self]; + }]; + } -- (FirebaseFirestoreFieldValueProxy *)increment:(id)value -{ - ENSURE_SINGLE_ARG(value, NSNumber); + - (FirebaseFirestoreFieldValueProxy *)increment:(id)value + { + ENSURE_SINGLE_ARG(value, NSNumber); - FIRFieldValue *fieldValue = [FIRFieldValue fieldValueForIntegerIncrement:[TiUtils intValue:value]]; - return [[FirebaseFirestoreFieldValueProxy alloc] _initWithPageContext:pageContext andFieldValue:fieldValue]; -} + FIRFieldValue *fieldValue = [FIRFieldValue fieldValueForIntegerIncrement:[TiUtils intValue:value]]; + return [[FirebaseFirestoreFieldValueProxy alloc] _initWithPageContext:pageContext andFieldValue:fieldValue]; + } -@end + @end diff --git a/ios/manifest b/ios/manifest index 55c54fc..eda43ea 100644 --- a/ios/manifest +++ b/ios/manifest @@ -2,7 +2,7 @@ # this is your module manifest and used by Titanium # during compilation, packaging, distribution, etc. # -version: 1.0.2 +version: 1.0.3 apiversion: 2 architectures: arm64 x86_64 mac: false From 2d14e2e556b8618475a7e18dda65fbe7184bae72 Mon Sep 17 00:00:00 2001 From: Douglas Alves Date: Sun, 24 Nov 2024 09:00:47 -0300 Subject: [PATCH 2/2] Fixed odd indentation --- ios/Classes/FirebaseFirestoreModule.m | 474 +++++++++++++------------- 1 file changed, 237 insertions(+), 237 deletions(-) diff --git a/ios/Classes/FirebaseFirestoreModule.m b/ios/Classes/FirebaseFirestoreModule.m index 3892ece..a01648a 100644 --- a/ios/Classes/FirebaseFirestoreModule.m +++ b/ios/Classes/FirebaseFirestoreModule.m @@ -1,256 +1,256 @@ - /** - * titanium-firebase-firestore - * - * Created by Hans Knöchel - */ - - #import "FirebaseFirestoreModule.h" - #import "TiBase.h" - #import "TiFirestoreUtils.h" - #import "TiHost.h" - #import "TiUtils.h" - - #import - - @implementation FirebaseFirestoreModule - - #pragma mark Internal - - - (id)moduleGUID - { - return @"01ba870c-6842-4b23-a8db-eb1eaffebf3f"; +/** + * titanium-firebase-firestore + * + * Created by Hans Knöchel + */ + +#import "FirebaseFirestoreModule.h" +#import "TiBase.h" +#import "TiFirestoreUtils.h" +#import "TiHost.h" +#import "TiUtils.h" + +#import + +@implementation FirebaseFirestoreModule + +#pragma mark Internal + +- (id)moduleGUID +{ + return @"01ba870c-6842-4b23-a8db-eb1eaffebf3f"; +} + +- (NSString *)moduleId +{ + return @"firebase.firestore"; +} + +- (void)addDocument:(id)params +{ + ENSURE_SINGLE_ARG(params, NSDictionary); + + KrollCallback *callback = params[@"callback"]; + NSString *collection = params[@"collection"]; + NSDictionary *data = params[@"data"]; // TODO: Parse "FIRFieldValue" proxy types + + __block FIRDocumentReference *ref = [[FIRFirestore.firestore collectionWithPath:collection] addDocumentWithData:data + completion:^(NSError *_Nullable error) { + if (error != nil) { + [callback call:@[ @{@"success" : @(NO), + @"error" : error.localizedDescription} ] + thisObject:self]; + return; + } + + [callback call:@[ @{@"success" : @(YES), + @"documentID" : NULL_IF_NIL(ref.documentID), + @"documentPath" : NULL_IF_NIL(ref.path)} ] + thisObject:self]; + }]; +} + +- (void)queryDocuments:(id)params +{ + ENSURE_SINGLE_ARG(params, NSDictionary); + KrollCallback *callback = params[@"callback"]; + NSString *collection = params[@"collection"]; + NSString *document = params[@"document"]; + + FIRCollectionReference *ref = [FIRFirestore.firestore collectionWithPath:collection]; + FIRDocumentReference *documentReference = [[FIRFirestore.firestore collectionWithPath:collection] documentWithPath:document]; + FIRQuery *query = [FIRFirestore.firestore collectionWithPath:params[@"path"]]; + + NSDictionary *parameters = params[@"parameters"]; + NSArray *whereConditions = params[@"where"]; + + for (id item in whereConditions) { + NSArray *condition = item; + NSString *fieldName = condition[0]; + NSString *op = condition[1]; + id value = condition[2]; + if ([op isEqualToString:@"=="]) { + query = [query queryWhereField:fieldName isEqualTo:value]; + } else if ([op isEqualToString:@"<"]) { + query = [query queryWhereField:fieldName isLessThan:value]; + } else if ([op isEqualToString:@"<="]) { + query = [query queryWhereField:fieldName isLessThanOrEqualTo:value]; + } else if ([op isEqualToString:@">"]) { + query = [query queryWhereField:fieldName isGreaterThan:value]; + } else if ([op isEqualToString:@">="]) { + query = [query queryWhereField:fieldName isGreaterThanOrEqualTo:value]; + } else if ([op isEqualToString:@"array-contains"]) { + query = [query queryWhereField:fieldName arrayContains:value]; + } else { + NSLog(@"[ERROR] Unhandled operator \"%@\" on field \"%@\"", op, fieldName); + // Unsupported operator } - - - (NSString *)moduleId - { - return @"firebase.firestore"; + } + + id limit = parameters[@"limit"]; + if (limit) { + NSNumber *length = limit; + query = [query queryLimitedTo:[length intValue]]; + } + + NSArray *orderBy = parameters[@"orderBy"]; + if (orderBy) { + for (id item in orderBy) { + NSArray *orderByParameters = item; + NSString *fieldName = orderByParameters[0]; + NSNumber *descending = orderByParameters[1]; + query = [query queryOrderedByField:fieldName descending:[descending boolValue]]; } - - - (void)addDocument:(id)params - { - ENSURE_SINGLE_ARG(params, NSDictionary); - - KrollCallback *callback = params[@"callback"]; - NSString *collection = params[@"collection"]; - NSDictionary *data = params[@"data"]; // TODO: Parse "FIRFieldValue" proxy types - - __block FIRDocumentReference *ref = [[FIRFirestore.firestore collectionWithPath:collection] addDocumentWithData:data - completion:^(NSError *_Nullable error) { - if (error != nil) { - [callback call:@[ @{@"success" : @(NO), - @"error" : error.localizedDescription} ] - thisObject:self]; - return; - } - - [callback call:@[ @{@"success" : @(YES), - @"documentID" : NULL_IF_NIL(ref.documentID), - @"documentPath" : NULL_IF_NIL(ref.path)} ] - thisObject:self]; - }]; + } + + id startAt = parameters[@"startAt"]; + if (startAt) { + NSArray *startAtValues = startAt; + query = [query queryStartingAtValues:startAtValues]; + } + + id startAfter = parameters[@"startAfter"]; + if (startAfter) { + NSArray *startAfterValues = startAfter; + query = [query queryStartingAfterValues:startAfterValues]; + } + + id endAt = parameters[@"endAt"]; + if (endAt) { + NSArray *endAtValues = endAt; + query = [query queryEndingAtValues:endAtValues]; + } + + id endBefore = parameters[@"endBefore"]; + if (endBefore) { + NSArray *endBeforeValues = endBefore; + query = [query queryEndingBeforeValues:endBeforeValues]; + } + + [query getDocumentsWithCompletion:^(FIRQuerySnapshot *_Nullable snapshot, NSError *_Nullable error) { + if (error != nil) { + [callback call:@[ @{ + @"success" : @(NO), + @"error" : error.localizedDescription + } ] + thisObject:self]; + return; } - - (void)queryDocuments:(id)params - { - ENSURE_SINGLE_ARG(params, NSDictionary); - KrollCallback *callback = params[@"callback"]; - NSString *collection = params[@"collection"]; - NSString *document = params[@"document"]; - - FIRCollectionReference *ref = [FIRFirestore.firestore collectionWithPath:collection]; - FIRDocumentReference *documentReference = [[FIRFirestore.firestore collectionWithPath:collection] documentWithPath:document]; - FIRQuery *query = [FIRFirestore.firestore collectionWithPath:params[@"path"]]; - - NSDictionary *parameters = params[@"parameters"]; - NSArray *whereConditions = params[@"where"]; - - for (id item in whereConditions) { - NSArray *condition = item; - NSString *fieldName = condition[0]; - NSString *op = condition[1]; - id value = condition[2]; - if ([op isEqualToString:@"=="]) { - query = [query queryWhereField:fieldName isEqualTo:value]; - } else if ([op isEqualToString:@"<"]) { - query = [query queryWhereField:fieldName isLessThan:value]; - } else if ([op isEqualToString:@"<="]) { - query = [query queryWhereField:fieldName isLessThanOrEqualTo:value]; - } else if ([op isEqualToString:@">"]) { - query = [query queryWhereField:fieldName isGreaterThan:value]; - } else if ([op isEqualToString:@">="]) { - query = [query queryWhereField:fieldName isGreaterThanOrEqualTo:value]; - } else if ([op isEqualToString:@"array-contains"]) { - query = [query queryWhereField:fieldName arrayContains:value]; - } else { - NSLog(@"[ERROR] Unhandled operator \"%@\" on field \"%@\"", op, fieldName); - // Unsupported operator - } - } - - id limit = parameters[@"limit"]; - if (limit) { - NSNumber *length = limit; - query = [query queryLimitedTo:[length intValue]]; - } - - NSArray *orderBy = parameters[@"orderBy"]; - if (orderBy) { - for (id item in orderBy) { - NSArray *orderByParameters = item; - NSString *fieldName = orderByParameters[0]; - NSNumber *descending = orderByParameters[1]; - query = [query queryOrderedByField:fieldName descending:[descending boolValue]]; - } - } - - id startAt = parameters[@"startAt"]; - if (startAt) { - NSArray *startAtValues = startAt; - query = [query queryStartingAtValues:startAtValues]; - } - - id startAfter = parameters[@"startAfter"]; - if (startAfter) { - NSArray *startAfterValues = startAfter; - query = [query queryStartingAfterValues:startAfterValues]; - } - - id endAt = parameters[@"endAt"]; - if (endAt) { - NSArray *endAtValues = endAt; - query = [query queryEndingAtValues:endAtValues]; - } - - id endBefore = parameters[@"endBefore"]; - if (endBefore) { - NSArray *endBeforeValues = endBefore; - query = [query queryEndingBeforeValues:endBeforeValues]; - } - - [query getDocumentsWithCompletion:^(FIRQuerySnapshot *_Nullable snapshot, NSError *_Nullable error) { - if (error != nil) { - [callback call:@[ @{ - @"success" : @(NO), - @"error" : error.localizedDescription - } ] - thisObject:self]; - return; - } - - NSMutableArray *> *documents = [NSMutableArray arrayWithCapacity:snapshot.documents.count]; - - // Map the documents to make sure it's a bridgeable type - [snapshot.documents enumerateObjectsUsingBlock:^(FIRQueryDocumentSnapshot *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) { - [documents addObject:[TiFirestoreUtils mappedFirestoreValue:obj.data]]; - }]; - [callback call:@[ @{ - @"success" : @(YES), - @"documents" : documents - } ] - thisObject:self]; - }]; + NSMutableArray *> *documents = [NSMutableArray arrayWithCapacity:snapshot.documents.count]; + + // Map the documents to make sure it's a bridgeable type + [snapshot.documents enumerateObjectsUsingBlock:^(FIRQueryDocumentSnapshot *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) { + [documents addObject:[TiFirestoreUtils mappedFirestoreValue:obj.data]]; + }]; + [callback call:@[ @{ + @"success" : @(YES), + @"documents" : documents + } ] + thisObject:self]; + }]; +} + +- (void)getDocuments:(id)params +{ + ENSURE_SINGLE_ARG(params, NSDictionary); + + KrollCallback *callback = params[@"callback"]; + NSString *collection = params[@"collection"]; + + [[FIRFirestore.firestore collectionWithPath:collection] getDocumentsWithCompletion:^(FIRQuerySnapshot *_Nullable snapshot, NSError *_Nullable error) { + if (error != nil) { + [callback call:@[ @{@"success" : @(NO), + @"error" : error.localizedDescription} ] + thisObject:self]; + return; } - - (void)getDocuments:(id)params - { - ENSURE_SINGLE_ARG(params, NSDictionary); + NSMutableArray *> *documents = [NSMutableArray arrayWithCapacity:snapshot.documents.count]; - KrollCallback *callback = params[@"callback"]; - NSString *collection = params[@"collection"]; + [snapshot.documents enumerateObjectsUsingBlock:^(FIRQueryDocumentSnapshot *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) { + [documents addObject:[TiFirestoreUtils mappedFirestoreValue:obj.data]]; + }]; - [[FIRFirestore.firestore collectionWithPath:collection] getDocumentsWithCompletion:^(FIRQuerySnapshot *_Nullable snapshot, NSError *_Nullable error) { - if (error != nil) { - [callback call:@[ @{@"success" : @(NO), - @"error" : error.localizedDescription} ] - thisObject:self]; - return; - } + [callback call:@[ @{@"success" : @(YES), + @"documents" : documents} ] + thisObject:self]; + }]; +} - NSMutableArray *> *documents = [NSMutableArray arrayWithCapacity:snapshot.documents.count]; +- (void)getSingleDocument:(id)params +{ + ENSURE_SINGLE_ARG(params, NSDictionary); - [snapshot.documents enumerateObjectsUsingBlock:^(FIRQueryDocumentSnapshot *_Nonnull obj, NSUInteger idx, BOOL *_Nonnull stop) { - [documents addObject:[TiFirestoreUtils mappedFirestoreValue:obj.data]]; - }]; + KrollCallback *callback = params[@"callback"]; + NSString *collection = params[@"collection"]; + NSString *document = params[@"document"]; - [callback call:@[ @{@"success" : @(YES), - @"documents" : documents} ] - thisObject:self]; - }]; - } - - - (void)getSingleDocument:(id)params - { - ENSURE_SINGLE_ARG(params, NSDictionary); - - KrollCallback *callback = params[@"callback"]; - NSString *collection = params[@"collection"]; - NSString *document = params[@"document"]; - - FIRDocumentReference *documentReference = [[FIRFirestore.firestore collectionWithPath:collection] documentWithPath:document]; + FIRDocumentReference *documentReference = [[FIRFirestore.firestore collectionWithPath:collection] documentWithPath:document]; - [documentReference getDocumentWithCompletion:^(FIRDocumentSnapshot *_Nullable snapshot, NSError *_Nullable error) { - if (error != nil) { - [callback call:@[ @{@"success" : @(NO), - @"error" : error.localizedDescription} ] - thisObject:self]; - return; - } - - [callback call:@[ @{@"success" : @(YES), - @"document" : [snapshot data]} ] - thisObject:self]; - }]; + [documentReference getDocumentWithCompletion:^(FIRDocumentSnapshot *_Nullable snapshot, NSError *_Nullable error) { + if (error != nil) { + [callback call:@[ @{@"success" : @(NO), + @"error" : error.localizedDescription} ] + thisObject:self]; + return; } - - (void)updateDocument:(id)params - { - ENSURE_SINGLE_ARG(params, NSDictionary); - - KrollCallback *callback = params[@"callback"]; - NSString *collection = params[@"collection"]; - NSDictionary *data = params[@"data"]; // TODO: Parse "FIRFieldValue" proxy types - NSString *document = params[@"document"]; - - [[[FIRFirestore.firestore collectionWithPath:collection] documentWithPath:document] setData:data - completion:^(NSError * _Nullable error) { - if (error != nil) { - [callback call:@[ @{@"success" : @(NO), - @"error" : error.localizedDescription} ] - thisObject:self]; - return; - } - - [callback call:@[ @{@"success" : @(YES)} ] thisObject:self]; - }]; + [callback call:@[ @{@"success" : @(YES), + @"document" : [snapshot data]} ] + thisObject:self]; + }]; +} + +- (void)updateDocument:(id)params +{ + ENSURE_SINGLE_ARG(params, NSDictionary); + + KrollCallback *callback = params[@"callback"]; + NSString *collection = params[@"collection"]; + NSDictionary *data = params[@"data"]; // TODO: Parse "FIRFieldValue" proxy types + NSString *document = params[@"document"]; + + [[[FIRFirestore.firestore collectionWithPath:collection] documentWithPath:document] setData:data + completion:^(NSError * _Nullable error) { + if (error != nil) { + [callback call:@[ @{@"success" : @(NO), + @"error" : error.localizedDescription} ] + thisObject:self]; + return; + } + + [callback call:@[ @{@"success" : @(YES)} ] thisObject:self]; + }]; +} + +- (void)deleteDocument:(id)params +{ + ENSURE_SINGLE_ARG(params, NSDictionary); + + KrollCallback *callback = params[@"callback"]; + NSString *collection = params[@"collection"]; + NSDictionary *data = params[@"data"]; + NSString *document = params[@"document"]; + + [[[FIRFirestore.firestore collectionWithPath:collection] documentWithPath:document] deleteDocumentWithCompletion:^(NSError *_Nullable error) { + if (error != nil) { + [callback call:@[ @{@"success" : @(NO), + @"error" : error.localizedDescription} ] + thisObject:self]; + return; } - - (void)deleteDocument:(id)params - { - ENSURE_SINGLE_ARG(params, NSDictionary); - - KrollCallback *callback = params[@"callback"]; - NSString *collection = params[@"collection"]; - NSDictionary *data = params[@"data"]; - NSString *document = params[@"document"]; - - [[[FIRFirestore.firestore collectionWithPath:collection] documentWithPath:document] deleteDocumentWithCompletion:^(NSError *_Nullable error) { - if (error != nil) { - [callback call:@[ @{@"success" : @(NO), - @"error" : error.localizedDescription} ] - thisObject:self]; - return; - } - - [callback call:@[ @{@"success" : @(YES)} ] thisObject:self]; - }]; - } + [callback call:@[ @{@"success" : @(YES)} ] thisObject:self]; + }]; +} - - (FirebaseFirestoreFieldValueProxy *)increment:(id)value - { - ENSURE_SINGLE_ARG(value, NSNumber); +- (FirebaseFirestoreFieldValueProxy *)increment:(id)value +{ + ENSURE_SINGLE_ARG(value, NSNumber); - FIRFieldValue *fieldValue = [FIRFieldValue fieldValueForIntegerIncrement:[TiUtils intValue:value]]; - return [[FirebaseFirestoreFieldValueProxy alloc] _initWithPageContext:pageContext andFieldValue:fieldValue]; - } + FIRFieldValue *fieldValue = [FIRFieldValue fieldValueForIntegerIncrement:[TiUtils intValue:value]]; + return [[FirebaseFirestoreFieldValueProxy alloc] _initWithPageContext:pageContext andFieldValue:fieldValue]; +} - @end +@end