Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e4104c8
feat(firestore): iOS implementation for Pipeline APIs
SelaseKay Mar 9, 2026
c269154
fix: conditionally import FIRPipelineBridge.h for iOS
SelaseKay Mar 9, 2026
1a36502
chore: add macOS support for FLTPipelineParser by linking to iOS impl…
SelaseKay Mar 9, 2026
b5dad03
fix: conditionally include FIRPipelineBridge.h for macOS support in F…
SelaseKay Mar 10, 2026
d1000b7
Merge branch 'firestore-pipelines-dart-api-v2' into firestore-pipelin…
SelaseKay Mar 11, 2026
70641d2
chore: add support for missing Expression function
SelaseKay Mar 11, 2026
e16f65a
refactor: clean up formatting in FLTPipelineParser.m for improved rea…
SelaseKay Mar 12, 2026
136363f
chore: enhance FLTPipelineParser with support for array and map expre…
SelaseKay Mar 12, 2026
be662d8
chore: implement conditional expression and current timestamp handlin…
SelaseKay Mar 13, 2026
cfd0867
chore: add 'find_nearest' stage support in FLTPipelineParser with val…
SelaseKay Mar 13, 2026
0cf5920
Merge branch 'firestore-pipelines-dart-api-v2' into firestore-pipelin…
SelaseKay Mar 13, 2026
64884bf
chore: introduce FLTFirebaseFirestoreErrorCodePipelineParse for impro…
SelaseKay Mar 16, 2026
906f1a3
Merge branch 'firestore-pipelines-dart-api-v2' into firestore-pipelin…
SelaseKay Mar 19, 2026
421d4f0
trigger CI
SelaseKay Mar 19, 2026
39b85e1
Merge branch 'firestore-pipelines-dart-api-v2' into firestore-pipelin…
SelaseKay Mar 19, 2026
2afcd07
Merge branch 'firestore-pipelines-dart-api-v2' into firestore-pipelin…
SelaseKay Mar 19, 2026
00ca6af
fix: update header inclusion logic for FirebaseFirestore in FLTPipeli…
SelaseKay Mar 19, 2026
0aaf46c
Merge branch 'firestore-pipelines-dart-api-v2' into firestore-pipelin…
SelaseKay Mar 19, 2026
e0ce705
Merge branch 'firestore-pipelines-dart-api-v2' into firestore-pipelin…
SelaseKay Mar 20, 2026
8355987
trigger CI
SelaseKay Mar 20, 2026
d71de1a
Merge branch 'firestore-pipelines-dart-api-v2' into firestore-pipelin…
SelaseKay Mar 20, 2026
01ade6a
chore: enhance FLTPipelineParser with new expression handling
SelaseKay Mar 20, 2026
1792a3b
Merge branch 'firestore-pipelines-dart-api-v2' into firestore-pipelin…
SelaseKay Mar 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#import "include/cloud_firestore/Private/FLTFirebaseFirestoreReader.h"
#import "include/cloud_firestore/Private/FLTFirebaseFirestoreUtils.h"
#import "include/cloud_firestore/Private/FLTLoadBundleStreamHandler.h"
#import "include/cloud_firestore/Private/FLTPipelineParser.h"
#import "include/cloud_firestore/Private/FLTQuerySnapshotStreamHandler.h"
#import "include/cloud_firestore/Private/FLTSnapshotsInSyncStreamHandler.h"
#import "include/cloud_firestore/Private/FLTTransactionStreamHandler.h"
Expand Down Expand Up @@ -73,6 +74,20 @@ - (NSString *)registerEventChannelWithPrefix:(NSString *)prefix

static NSCache<NSNumber *, NSString *> *_serverTimestampMap;

static id _Nullable FLTPipelineNullSafe(id value) {
return (value == nil || [value isKindOfClass:[NSNull class]]) ? nil : value;
}

static NSNumber *_Nullable FLTPipelineTimestampToMs(id value) {
if (!value) return nil;
if ([value isKindOfClass:[NSNumber class]]) return value;
if ([value isKindOfClass:[FIRTimestamp class]]) {
FIRTimestamp *ts = value;
return @((int64_t)ts.seconds * 1000 + (int64_t)ts.nanoseconds / 1000000);
}
return nil;
}

@implementation FLTFirebaseFirestorePlugin {
NSMutableDictionary<NSString *, FlutterEventChannel *> *_eventChannels;
NSMutableDictionary<NSString *, NSObject<FlutterStreamHandler> *> *_streamHandlers;
Expand Down Expand Up @@ -883,4 +898,66 @@ - (void)aggregateQueryApp:(nonnull FirestorePigeonFirebaseApp *)app
}];
}

- (void)executePipelineApp:(nonnull FirestorePigeonFirebaseApp *)app
stages:(nonnull NSArray<NSDictionary<NSString *, id> *> *)stages
options:(nullable NSDictionary<NSString *, id> *)options
completion:(nonnull void (^)(PigeonPipelineSnapshot *_Nullable,
FlutterError *_Nullable))completion {
FIRFirestore *firestore = [self getFIRFirestoreFromAppNameFromPigeon:app];

[FLTPipelineParser
executePipelineWithFirestore:firestore
stages:stages
options:options
completion:^(id _Nullable snapshot, NSError *_Nullable error) {
if (error) {
completion(nil, [self convertToFlutterError:error]);
return;
}
if (snapshot == nil) {
completion(
nil,
[FlutterError errorWithCode:@"error"
message:@"Pipeline execution returned no result"
details:nil]);
return;
}

NSMutableArray<PigeonPipelineResult *> *pigeonResults =
[NSMutableArray array];
NSArray *results = [snapshot results];
if ([results isKindOfClass:[NSArray class]]) {
for (id result in results) {
id ref = [result reference];
NSString *path = (ref && [ref respondsToSelector:@selector(path)])
? [ref path]
: FLTPipelineNullSafe([result documentID]);
NSNumber *createTime =
FLTPipelineTimestampToMs([result valueForKey:@"create_time"]);
NSNumber *updateTime =
FLTPipelineTimestampToMs([result valueForKey:@"update_time"]);
NSDictionary *data = FLTPipelineNullSafe([result data]);
PigeonPipelineResult *pigeonResult =
[PigeonPipelineResult makeWithDocumentPath:path
createTime:createTime
updateTime:updateTime
data:data];
[pigeonResults addObject:pigeonResult];
}
}

NSNumber *executionTime =
FLTPipelineTimestampToMs([snapshot execution_time]);
if (executionTime == nil) {
executionTime =
@((int64_t)([[NSDate date] timeIntervalSince1970] * 1000));
}

PigeonPipelineSnapshot *pigeonSnapshot =
[PigeonPipelineSnapshot makeWithResults:pigeonResults
executionTime:executionTime];
completion(pigeonSnapshot, nil);
}];
}

@end
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ - (FlutterStandardReader *_Nonnull)readerWithData:(NSData *)data {

NSMutableDictionary<NSString *, FLTFirebaseFirestoreExtension *> *firestoreInstanceCache;

const NSInteger FLTFirebaseFirestoreErrorCodePipelineParse = -1;

@implementation FLTFirebaseFirestoreUtils

+ (NSString *)generateKeyForAppName:(NSString *)appName andDatabaseURL:(NSString *)databaseURL {
Expand Down Expand Up @@ -240,6 +242,11 @@ + (NSArray *)ErrorCodeAndMessageFromNSError:(NSError *)error {
code = @"unknown";
message = @"Unknown error or an error from a different error domain.";
break;
case FLTFirebaseFirestoreErrorCodePipelineParse:
code = @"parse-error";
message = (error.localizedDescription.length > 0) ? error.localizedDescription
: @"An unknown error occurred.";
break;
default:
code = @"unknown";
message = @"An unknown error occurred.";
Expand Down
Loading
Loading