Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
90bd9b5
feat(firestore): add support for Pipeline APIs
SelaseKay Feb 6, 2026
1c69d01
feat(firestore): implement pipeline execution and stages with options
SelaseKay Feb 11, 2026
1094fd0
refactor: change PipelineSerializable to mixin and update Constant cl…
SelaseKay Feb 12, 2026
89eb198
chore: add `Expression` functions
SelaseKay Feb 12, 2026
d92a2b0
chore: add support for Pigeon
SelaseKay Feb 13, 2026
b4089d8
chore: implement pipeline execution and expression parsing utilities …
SelaseKay Feb 17, 2026
7d90353
chore: enhance PigeonPipelineResult to support nullable fields and ad…
SelaseKay Feb 18, 2026
6fbd3e4
chore: enhance pipeline stage handling
SelaseKay Feb 20, 2026
3e557c6
chore: refactor sorting functionality in pipeline stages to support m…
SelaseKay Feb 24, 2026
d3c2eeb
chore: implement iOS support for Firestore pipeline execution
SelaseKay Feb 24, 2026
b4f8466
Merge branch 'feat/firestore-pipelines' into feat-firestore-pipelines
SelaseKay Feb 24, 2026
d7bc27c
refactor: move aggregate classes to pipeline_aggregate.dart
SelaseKay Feb 25, 2026
85d87e6
feat: enhance expression parsing in FLTPipelineParser to support addi…
SelaseKay Feb 25, 2026
6699324
fix: update args type in _UnnestStage to use a more specific map type
SelaseKay Feb 25, 2026
59c0b88
feat: add filter expression parsing to FLTPipelineParser for enhanced…
SelaseKay Feb 25, 2026
642c0de
fix: handle null values in parseConstantValue
SelaseKay Feb 27, 2026
0a06aea
feat: introduce keyForExpressionMap method in FLTPipelineParser for i…
SelaseKay Feb 27, 2026
1b29c4d
feat: bump Firebase JS SDK to 12.9.0 (#18043)
SelaseKay Feb 27, 2026
fd07be0
fix: use builtin GITHUB_TOKEN instead of explicit secret (#18031)
morganchen12 Feb 27, 2026
fed585f
refactor(fdc): Support for entityId path extensions and hardening (#1…
aashishpatil-g Feb 27, 2026
2334cf0
chore: fix formatting (#18044)
SelaseKay Mar 2, 2026
f2109de
Merge branch 'feat/firestore-pipelines' into feat-firestore-pipelines
SelaseKay Mar 2, 2026
dfab619
feat: implement Firestore pipeline support for web
SelaseKay Mar 3, 2026
9061ea8
feat: enhance Firestore pipeline support for web
SelaseKay Mar 4, 2026
00f23b4
fix
SelaseKay Mar 4, 2026
26a9294
chore: clean up and refactor
SelaseKay Mar 5, 2026
b3d8e53
chore: add more interop and clean up code
SelaseKay Mar 6, 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
4 changes: 3 additions & 1 deletion .github/workflows/pr_title.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ on:

jobs:
validate:
permissions:
pull-requests: read
runs-on: ubuntu-latest
steps:
- uses: amannn/action-semantic-pull-request@0723387faaf9b38adef4775cd42cfd5155ed6017
env:
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
import com.google.firebase.firestore.MemoryCacheSettings;
import com.google.firebase.firestore.PersistentCacheIndexManager;
import com.google.firebase.firestore.PersistentCacheSettings;
import com.google.firebase.firestore.Pipeline;
import com.google.firebase.firestore.PipelineResult;
import com.google.firebase.firestore.Query;
import com.google.firebase.firestore.QuerySnapshot;
import com.google.firebase.firestore.SetOptions;
Expand All @@ -52,6 +54,7 @@
import io.flutter.plugins.firebase.firestore.streamhandler.TransactionStreamHandler;
import io.flutter.plugins.firebase.firestore.utils.ExceptionConverter;
import io.flutter.plugins.firebase.firestore.utils.PigeonParser;
import io.flutter.plugins.firebase.firestore.utils.PipelineParser;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
Expand Down Expand Up @@ -983,4 +986,73 @@ public void documentReferenceSnapshot(
parameters.getServerTimestampBehavior()),
PigeonParser.parseListenSource(source))));
}

@Override
public void executePipeline(
@NonNull GeneratedAndroidFirebaseFirestore.FirestorePigeonFirebaseApp app,
@NonNull List<Map<String, Object>> stages,
@Nullable Map<String, Object> options,
@NonNull
GeneratedAndroidFirebaseFirestore.Result<
GeneratedAndroidFirebaseFirestore.PigeonPipelineSnapshot>
result) {
cachedThreadPool.execute(
() -> {
try {
FirebaseFirestore firestore = getFirestoreFromPigeon(app);

// Execute pipeline using Android Firestore SDK
Pipeline.Snapshot snapshot = PipelineParser.executePipeline(firestore, stages, options);

// Convert Pipeline.Snapshot to PigeonPipelineSnapshot
List<GeneratedAndroidFirebaseFirestore.PigeonPipelineResult> pipelineResults =
new ArrayList<>();

// Iterate through snapshot results
for (PipelineResult pipelineResult : snapshot.getResults()) {
GeneratedAndroidFirebaseFirestore.PigeonPipelineResult.Builder resultBuilder =
new GeneratedAndroidFirebaseFirestore.PigeonPipelineResult.Builder();
if (pipelineResult.getRef() != null) {
resultBuilder.setDocumentPath(pipelineResult.getRef().getPath());
}

// Convert timestamps (assuming they're in milliseconds)
if (pipelineResult.getCreateTime() != null) {
resultBuilder.setCreateTime(pipelineResult.getCreateTime().toDate().getTime());
} else {
resultBuilder.setCreateTime(0L);
}

if (pipelineResult.getUpdateTime() != null) {
resultBuilder.setUpdateTime(pipelineResult.getUpdateTime().toDate().getTime());
} else {
resultBuilder.setUpdateTime(0L);
}
Comment on lines +1020 to +1030
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The PigeonPipelineResult class defines createTime and updateTime as nullable Longs. Instead of setting them to 0L when the source timestamp is null, it would be more consistent to set them to null. This avoids forcing the Dart side to treat 0 as a special case for a missing timestamp.

Suggested change
if (pipelineResult.getCreateTime() != null) {
resultBuilder.setCreateTime(pipelineResult.getCreateTime().toDate().getTime());
} else {
resultBuilder.setCreateTime(0L);
}
if (pipelineResult.getUpdateTime() != null) {
resultBuilder.setUpdateTime(pipelineResult.getUpdateTime().toDate().getTime());
} else {
resultBuilder.setUpdateTime(0L);
}
if (pipelineResult.getCreateTime() != null) {
resultBuilder.setCreateTime(pipelineResult.getCreateTime().toDate().getTime());
} else {
resultBuilder.setCreateTime(null);
}
if (pipelineResult.getUpdateTime() != null) {
resultBuilder.setUpdateTime(pipelineResult.getUpdateTime().toDate().getTime());
} else {
resultBuilder.setUpdateTime(null);
}


Map<String, Object> data = pipelineResult.getData();
if (data != null) {
resultBuilder.setData(data);
}

pipelineResults.add(resultBuilder.build());
}

// Build the snapshot
GeneratedAndroidFirebaseFirestore.PigeonPipelineSnapshot.Builder snapshotBuilder =
new GeneratedAndroidFirebaseFirestore.PigeonPipelineSnapshot.Builder();
snapshotBuilder.setResults(pipelineResults);

// Set execution time (use current time if not available from snapshot)
if (snapshot.getExecutionTime() != null) {
snapshotBuilder.setExecutionTime(snapshot.getExecutionTime().toDate().getTime());
} else {
snapshotBuilder.setExecutionTime(System.currentTimeMillis());
}

result.success(snapshotBuilder.build());
} catch (Exception e) {
ExceptionConverter.sendErrorToFlutter(result, e);
}
});
}
}
Loading
Loading