Repository navigation
feat(firestore): add DML stages, literals source, and atomic execution option to Node SDK pipelines - #9118
Merged
Conversation
Contributor
There was a problem hiding this comment.
Code Review
This pull request introduces support for DML stages (insert, upsert, and literals) and an atomic execution option within Firestore pipelines, complete with updated type definitions and tests. The feedback highlights a critical transaction precedence issue where the atomic option could bypass active transactions, an options-parsing bug in the literals stage, and the need for recursive user data validation to prevent nested custom classes from bypassing checks.
4 tasks done
…erals source, and atomic execution option to Node SDK pipelines
…cution and test atomic: false
wu-hui
force-pushed
the
feat-node-dml
branch
2 times, most recently
from
October 6, 2026 15:33
8360e1e to
8300c66
Compare
Merged
…line API conventions
Follow the existing Pipeline stage convention of `stage(requiredArg)` /
variadic convenience overloads plus a single `stage(options)` overload,
where the options object carries the required params.
- literals (PipelineSource and Pipeline): remove the
`(documents, options?)` overload; `documents` is now required in
LiteralsStageOptions.
- update: remove the `Record<string, Expression> | Map` overload (not in
the API proposal, no precedent, and indistinguishable at runtime from
an options object); add `update(options: UpdateStageOptions)` with
`transformedFields`.
- delete: add `delete(options: DeleteStageOptions)` so rawOptions can be
provided.
- upsert: remove the `(additionalFields[], options?)` overload; use
`upsert({additionalFields, ...})` instead.
…verloads Follow the precedent set by database() for stages with no required params, consistent with delete().
…tageOptions transforms was an earlier name for additionalFields that was never released in the Node or Web SDKs, so the deprecated alias is unnecessary API surface.
…neSource only literals is a source stage (LiteralsSource). It was only ever used and tested as the first stage via PipelineSource, and the Web SDK exposes it only on PipelineSource.
…ents FieldValue sentinels (serverTimestamp(), increment(), arrayUnion(), arrayRemove(), delete(), ...) cannot be represented in an encoded pipeline. Previously they were silently dropped from literal documents (and a document containing only sentinels failed with an INTERNAL serialization error). Literal documents are now validated recursively and sentinels throw the same error as the Web SDK: Function literals() called with invalid data. <method>() can only be used with update() and set() (found in field <path>) Nested values with user data are now also validated, not just top-level fields.
hasUserData() dereferences its argument, so a null value in a literal document crashed _validateUserData with a TypeError.
…ents
The backend only evaluates expressions in the top-level fields of a
literal document, so nested expressions (e.g. {a: {b: add(...)}}) failed
with "Value type is not supported: FUNCTION_VALUE". Encode each document
as a top-level mapValue whose fields are converted with
valueToDefaultExpr, so nested objects and arrays become map() and array()
expressions, matching rawStage() and expression arguments.
Undefined values are now rejected unless ignoreUndefinedProperties is
enabled, preserving the previous serializer behavior.
…ic option Describe how collection and documentIdExpression determine the target document, that a string documentIdExpression is a field name (use constant() for a fixed ID), that upsert requires collection when documentIdExpression is set, and what atomic does. Behavior verified against nightly; adds system tests for the field-name semantics and the upsert collection requirement.
Backport documentation refinements from the Web SDK (firebase-js-sdk#10200): - Upsert with only `collection` set auto-generates an ID when the input document has no ID (e.g. from literals()). - Insert/upsert with neither `collection` nor `documentIdExpression` set fail for input documents that have no ID. - update/insert/upsert method docs now point to the stage options types for how the target document is determined.
Port of firebase-js-sdk a6948d73f. Passing `collection: ''` to insert() or upsert() now throws "Function insert()/upsert() cannot be called with an empty collection path." instead of silently falling back to the input document's parent collection.
Verified against the nightly backend: a non-atomic update skips input documents whose target does not exist (not counted in documents_modified), while an atomic update fails with NOT_FOUND and updates nothing. Adds system tests for both cases.
MarkDuckworth
approved these changes
Oct 19, 2026
dlarocque
approved these changes
Oct 20, 2026
| * Performs a delete operation on documents from previous stages. | ||
| * | ||
| * @param options - Options defining how this Delete stage is evaluated. | ||
| * @return A new {@code Pipeline} object with this stage appended to the stage list. |
Contributor
There was a problem hiding this comment.
Not a blocker, since it's an existing issue throughout the SDK it seems. This comment applies to multiple APIs throughout the file.
@codeis Javadoc style tag- These docs aren't in sync with those in
firestore.d.ts
gcf-merge-on-green Bot
pushed a commit
that referenced
this pull request
Oct 22, 2026
## Description Restores the release-please changelog entry for Firestore pipeline DML stages (#9118). This ensures the release only has one change log entry for the DML PR which merged without squash and merge. Added blank newline to firestore changelog to force release please to run for this PR, but the affected file will be overwritten in the release PR. BEGIN_COMMIT_OVERRIDE feat(firestore): add DML stages (insert, upsert, delete, update), literals source, and atomic execution option to Node SDK pipelines END_COMMIT_OVERRIDE
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds full support for DML stages (insert, upsert, delete, update), literals data source stage, and atomic execution option to Node SDK Firestore pipelines to achieve parity with Web SDK.
BEGIN_COMMIT_OVERRIDE
chore(firestore): add DML stages (insert, upsert, delete, update), literals source, and atomic execution option to Node SDK pipelines
END_COMMIT_OVERRIDE