diff --git a/packages/firestore/ios/RNFBFirestore/RNFBFirestoreCollectionModule.m b/packages/firestore/ios/RNFBFirestore/RNFBFirestoreCollectionModule.m index 963f6fec11..4182acc5f8 100644 --- a/packages/firestore/ios/RNFBFirestore/RNFBFirestoreCollectionModule.m +++ b/packages/firestore/ios/RNFBFirestore/RNFBFirestoreCollectionModule.m @@ -216,6 +216,83 @@ - (void)invalidate { }]; } +RCT_EXPORT_METHOD(aggregateQuery + : (FIRApp *)firebaseApp + : (NSString *)databaseId + : (NSString *)path + : (NSString *)type + : (NSArray *)filters + : (NSArray *)orders + : (NSDictionary *)options + : (NSArray *)aggregateQueries + : (RCTPromiseResolveBlock)resolve + : (RCTPromiseRejectBlock)reject) { + FIRFirestore *firestore = [RNFBFirestoreCommon getFirestoreForApp:firebaseApp + databaseId:databaseId]; + FIRQuery *query = [RNFBFirestoreCommon getQueryForFirestore:firestore path:path type:type]; + + NSMutableArray *aggregateFields = + [[NSMutableArray alloc] init]; + + for (NSDictionary *aggregateQuery in aggregateQueries) { + NSString *aggregateType = aggregateQuery[@"aggregateType"]; + NSString *fieldPath = aggregateQuery[@"field"]; + assert(aggregateType); + assert(fieldPath); + + if([aggregateType isEqualToString:@"count"]){ + [aggregateFields addObject:[FIRAggregateField aggregateFieldForCount]]; + } else if([aggregateType isEqualToString:@"sum"]){ + [aggregateFields + addObject:[FIRAggregateField aggregateFieldForSumOfField:fieldPath]]; + } else if([aggregateType isEqualToString:@"average"]){ + [aggregateFields + addObject:[FIRAggregateField aggregateFieldForAverageOfField:fieldPath]]; + } else { + NSString *reason = [@"Invalid Aggregate Type: " stringByAppendingString:aggregateType]; + @throw [NSException exceptionWithName:@"RNFB Firestore: Invalid Aggregate Type" + reason:reason + userInfo:nil]; + } + } + + FIRAggregateQuery *aggregateQuery = [query aggregate:aggregateFields]; + + [aggregateQuery + aggregationWithSource:FIRAggregateSourceServer + completion:^(FIRAggregateQuerySnapshot *_Nullable snapshot, + NSError *_Nullable error) { + if (error) { + [RNFBFirestoreCommon promiseRejectFirestoreException:reject error:error]; + } else { + NSMutableDictionary *snapshotMap = [NSMutableDictionary dictionary]; + + for (NSDictionary *aggregateQuery in aggregateQueries) { + NSString *aggregateType = aggregateQuery[@"aggregateType"]; + NSString *fieldPath = aggregateQuery[@"field"]; + NSString *key = aggregateQuery[@"key"]; + assert(key); + + if([aggregateType isEqualToString:@"count"]){ + snapshotMap[key] = snapshot.count; + } else if([aggregateType isEqualToString:@"sum"]){ + NSNumber *sum = [snapshot + valueForAggregateField:[FIRAggregateField + aggregateFieldForSumOfField:fieldPath]]; + snapshotMap[key] = sum; + } else if([aggregateType isEqualToString:@"average"]){ + NSNumber *average = [snapshot + valueForAggregateField: + [FIRAggregateField + aggregateFieldForAverageOfField:fieldPath]]; + snapshotMap[key] = (average == nil ? [NSNull null] : average); + } + } + resolve(snapshotMap); + } + }]; +} + RCT_EXPORT_METHOD(collectionGet : (FIRApp *)firebaseApp : (NSString *)databaseId