Skip to content

feat(firestore): Add ifNull and coalesce expressions #9753

Open
milaGGL wants to merge 10 commits intomainfrom
mila/ifnull_coalesce
Open

feat(firestore): Add ifNull and coalesce expressions #9753
milaGGL wants to merge 10 commits intomainfrom
mila/ifnull_coalesce

Conversation

@milaGGL
Copy link
Copy Markdown
Contributor

@milaGGL milaGGL commented Mar 25, 2026

Add support for ifNull and coalesce.

@milaGGL milaGGL requested review from a team as code owners March 25, 2026 18:16
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 25, 2026

🦋 Changeset detected

Latest commit: 2b30319

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
firebase Minor
@firebase/firestore Minor
@firebase/firestore-compat Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances Firestore's data manipulation capabilities by introducing two new pipeline expressions: ifNull and coalesce. These additions provide developers with more powerful and flexible tools for handling null or absent values directly within their queries, streamlining data processing and reducing the need for client-side logic. The changes involve updates to the core expression logic, API definitions, documentation, and test suites to ensure full functionality and clarity.

Highlights

  • New Pipeline Expressions: Added support for ifNull and coalesce pipeline expressions in Firestore, providing more robust null handling capabilities.
  • API Surface Expansion: Introduced new API declarations for ifNull and coalesce functions and Expression methods across both Firestore and Firestore Lite.
  • Documentation Updates: Updated developer documentation and API review files to reflect the new ifNull and coalesce expressions, including usage examples.
  • Test Coverage: Included comprehensive integration and unit tests to validate the functionality of the new ifNull and coalesce expressions.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for new pipeline expressions, ifNull and coalesce, in Firebase Firestore and Firestore Lite. The changes include adding API definitions, implementing the expressions in the Expression class, updating documentation, and adding integration tests. Feedback from the review primarily focuses on documentation improvements, such as correcting capitalization inconsistencies, fixing formatting errors with [Expression] links, and ensuring descriptions accurately reflect that ifNull and coalesce handle both null and absent values.

I am having trouble creating individual review comments. Click here to see my feedback.

docs-devsite/firestore_lite_pipelines.expression.md (81)

medium

There's a capitalization inconsistency in the description. "Returns" should be in lowercase to be consistent with other descriptions in this file.

|  [coalesce(replacement, others)](./firestore_lite_pipelines.expression.md#expressioncoalesce) |  | <b><i>(Public Preview)</i></b> Creates an expression that returns the first non-null, non-absent argument, without evaluating the rest of the arguments. When all arguments are null or absent, returns the last argument. |

docs-devsite/firestore_lite_pipelines.expression.md (1513)

medium

There's a capitalization inconsistency in the description. "Returns" should be in lowercase to be consistent with standard documentation style.

Creates an expression that returns the first non-null, non-absent argument, without evaluating the rest of the arguments. When all arguments are null or absent, returns the last argument.

docs-devsite/firestore_lite_pipelines.expression.md (2599)

medium

There's a formatting error in the documentation. The backslash before [Expression] should be removed to correctly render the link.

A new [Expression] representing the ifNull operation.

docs-devsite/firestore_lite_pipelines.expression.md (2633)

medium

There's a formatting error in the documentation. The backslash before [Expression] should be removed to correctly render the link.

A new [Expression] representing the ifNull operation.

docs-devsite/firestore_lite_pipelines.md (95)

medium

There's a capitalization inconsistency in the description. "Returns" should be in lowercase to be consistent with other descriptions in this file.

|  [coalesce(expression, replacement, others)](./firestore_lite_pipelines.md#coalesce_00859cb) | <b><i>(Public Preview)</i></b> Creates an expression that returns the first non-null, non-absent argument, without evaluating the rest of the arguments. When all arguments are null or absent, returns the last argument. |

docs-devsite/firestore_lite_pipelines.md (174)

medium

There's a capitalization inconsistency in the description. "Returns" should be in lowercase to be consistent with other descriptions in this file.

|  [coalesce(fieldName, replacement, others)](./firestore_lite_pipelines.md#coalesce_249958e) | <b><i>(Public Preview)</i></b> Creates an expression that returns the first non-null, non-absent argument, without evaluating the rest of the arguments. When all arguments are null or absent, returns the last argument. |

docs-devsite/firestore_lite_pipelines.md (290-291)

medium

The description for ifNull is incomplete. It should mention that it also checks for absent values, not just null values, to be consistent with the implementation and other parts of the documentation.

|  [ifNull(ifExpr, elseExpr)](./firestore_lite_pipelines.md#ifnull_0e6d161) | <b><i>(Public Preview)</i></b> Creates an expression that returns the <code>elseExpr</code> argument if <code>ifExpr</code> is null or absent, else return the result of the <code>ifExpr</code> argument evaluation. |
|  [ifNull(ifExpr, elseValue)](./firestore_lite_pipelines.md#ifnull_c34e5ed) | <b><i>(Public Preview)</i></b> Creates an expression that returns the <code>elseValue</code> argument if <code>ifExpr</code> is null or absent, else return the result of the <code>ifExpr</code> argument evaluation. |

docs-devsite/firestore_lite_pipelines.md (2637)

medium

There's a capitalization inconsistency in the description. "Returns" should be in lowercase to be consistent with standard documentation style.

Creates an expression that returns the first non-null, non-absent argument, without evaluating the rest of the arguments. When all arguments are null or absent, returns the last argument.

docs-devsite/firestore_lite_pipelines.md (9189)

medium

The description for ifNull is incomplete. It should mention that it also checks for absent values, not just null values, to be consistent with the implementation.

Creates an expression that returns the `elseExpr` argument if `ifExpr` is null or absent, else return the result of the `ifExpr` argument evaluation.

docs-devsite/firestore_lite_pipelines.md (9236)

medium

The description for the ifExpr parameter is inconsistent. It should state that it checks for "null or absence" to be accurate.

|  ifExpr | [Expression](./firestore_lite_pipelines.expression.md#expression_class) | The expression to check for null or absence. |

docs-devsite/firestore_lite_pipelines.md (9243)

medium

There's a formatting error in the documentation. The backslash before [Expression] should be removed to correctly render the link.

A new [Expression] representing the ifNull operation.

docs-devsite/firestore_lite_pipelines.md (9381)

medium

There's a formatting error in the documentation. The backslash before [ifFieldName] should be removed to correctly render the link.

|  elseValue | unknown | The value that will be returned if [ifFieldName] is null or absent. |

docs-devsite/firestore_pipelines.expression.md (81)

medium

There's a capitalization inconsistency in the description. "Returns" should be in lowercase to be consistent with other descriptions in this file.

|  [coalesce(replacement, others)](./firestore_pipelines.expression.md#expressioncoalesce) |  | <b><i>(Public Preview)</i></b> Creates an expression that returns the first non-null, non-absent argument, without evaluating the rest of the arguments. When all arguments are null or absent, returns the last argument. |

docs-devsite/firestore_pipelines.expression.md (1513)

medium

There's a capitalization inconsistency in the description. "Returns" should be in lowercase to be consistent with standard documentation style.

Creates an expression that returns the first non-null, non-absent argument, without evaluating the rest of the arguments. When all arguments are null or absent, returns the last argument.

docs-devsite/firestore_pipelines.expression.md (2599)

medium

There's a formatting error in the documentation. The backslash before [Expression] should be removed to correctly render the link.

A new [Expression] representing the ifNull operation.

docs-devsite/firestore_pipelines.expression.md (2633)

medium

There's a formatting error in the documentation. The backslash before [Expression] should be removed to correctly render the link.

A new [Expression] representing the ifNull operation.

docs-devsite/firestore_pipelines.md (95)

medium

There's a capitalization inconsistency in the description. "Returns" should be in lowercase to be consistent with other descriptions in this file.

|  [coalesce(expression, replacement, others)](./firestore_pipelines.md#coalesce_00859cb) | <b><i>(Public Preview)</i></b> Creates an expression that returns the first non-null, non-absent argument, without evaluating the rest of the arguments. When all arguments are null or absent, returns the last argument. |

docs-devsite/firestore_pipelines.md (174)

medium

There's a capitalization inconsistency in the description. "Returns" should be in lowercase to be consistent with other descriptions in this file.

|  [coalesce(fieldName, replacement, others)](./firestore_pipelines.md#coalesce_249958e) | <b><i>(Public Preview)</i></b> Creates an expression that returns the first non-null, non-absent argument, without evaluating the rest of the arguments. When all arguments are null or absent, returns the last argument. |

docs-devsite/firestore_pipelines.md (290-291)

medium

The description for ifNull is incomplete. It should mention that it also checks for absent values, not just null values, to be consistent with the implementation and other parts of the documentation.

|  [ifNull(ifExpr, elseExpr)](./firestore_pipelines.md#ifnull_0e6d161) | <b><i>(Public Preview)</i></b> Creates an expression that returns the <code>elseExpr</code> argument if <code>ifExpr</code> is null or absent, else return the result of the <code>ifExpr</code> argument evaluation. |
|  [ifNull(ifExpr, elseValue)](./firestore_pipelines.md#ifnull_c34e5ed) | <b><i>(Public Preview)</i></b> Creates an expression that returns the <code>elseValue</code> argument if <code>ifExpr</code> is null or absent, else return the result of the <code>ifExpr</code> argument evaluation. |

docs-devsite/firestore_pipelines.md (2643)

medium

There's a capitalization inconsistency in the description. "Returns" should be in lowercase to be consistent with standard documentation style.

Creates an expression that returns the first non-null, non-absent argument, without evaluating the rest of the arguments. When all arguments are null or absent, returns the last argument.

docs-devsite/firestore_pipelines.md (9195)

medium

The description for ifNull is incomplete. It should mention that it also checks for absent values, not just null values, to be consistent with the implementation.

Creates an expression that returns the `elseExpr` argument if `ifExpr` is null or absent, else return the result of the `ifExpr` argument evaluation.

docs-devsite/firestore_pipelines.md (9242)

medium

The description for the ifExpr parameter is inconsistent. It should state that it checks for "null or absence" to be accurate.

|  ifExpr | [Expression](./firestore_pipelines.expression.md#expression_class) | The expression to check for null or absence. |

docs-devsite/firestore_pipelines.md (9249)

medium

There's a formatting error in the documentation. The backslash before [Expression] should be removed to correctly render the link.

A new [Expression] representing the ifNull operation.

docs-devsite/firestore_pipelines.md (9387)

medium

There's a formatting error in the documentation. The backslash before [ifFieldName] should be removed to correctly render the link.

|  elseValue | unknown | The value that will be returned if [ifFieldName] is null or absent. |

packages/firestore/src/lite-api/expressions.ts (3187)

medium

There's a capitalization inconsistency in the JSDoc. "Returns" should be in lowercase to follow standard JSDoc conventions.

   * Creates an expression that returns the first non-null, non-absent argument, without evaluating

packages/firestore/src/lite-api/expressions.ts (10600-10601)

medium

The JSDoc for ifNull is incomplete. It should mention that it also checks for absent values, not just null values, to be consistent with the implementation.

 * Creates an expression that returns the `elseExpr` argument if `ifExpr` is null or absent, else
 * return the result of the `ifExpr` argument evaluation.

packages/firestore/src/lite-api/expressions.ts (10618-10619)

medium

The JSDoc for ifNull is incomplete. It should mention that it also checks for absent values, not just null values, to be consistent with the implementation.

 * Creates an expression that returns the `elseValue` argument if `ifExpr` is null or absent, else
 * return the result of the `ifExpr` argument evaluation.

packages/firestore/src/lite-api/expressions.ts (10676)

medium

There's a capitalization inconsistency in the JSDoc. "Returns" should be in lowercase to follow standard JSDoc conventions.

 * Creates an expression that returns the first non-null, non-absent argument, without evaluating

packages/firestore/src/lite-api/expressions.ts (10699)

medium

There's a capitalization inconsistency in the JSDoc. "Returns" should be in lowercase to follow standard JSDoc conventions.

 * Creates an expression that returns the first non-null, non-absent argument, without evaluating

@milaGGL
Copy link
Copy Markdown
Contributor Author

milaGGL commented Mar 27, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces support for the ifNull and coalesce pipeline expressions in Firestore and Firestore Lite. The implementation includes adding these as static functions and instance methods on the Expression class, updating API review files, and providing comprehensive documentation and integration tests. The review feedback identifies minor documentation issues, such as rendering artifacts in markdown blockquotes and incomplete sentences that fail to properly contrast ifNull with ifAbsent.

@dlarocque
Copy link
Copy Markdown
Contributor

Is CI failing because these are not yet in prod? https://github.com/firebase/firebase-js-sdk/actions/runs/23653752018/job/68906986246?pr=9753

Copy link
Copy Markdown
Contributor

@dlarocque dlarocque left a comment

Choose a reason for hiding this comment

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

LGTM after removing @beta tags.

}

/**
* @beta
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

After #9772 these beta tags will be removed. Can you remove them from this PR?

Copy link
Copy Markdown
Contributor

@yvonnep165 yvonnep165 left a comment

Choose a reason for hiding this comment

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

LGTM pending the auto checks results.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants