Skip to content

Commit 6041509

Browse files
authored
feat(firestore): add isType expression (#9484)
1 parent 659d9bb commit 6041509

File tree

12 files changed

+660
-53
lines changed

12 files changed

+660
-53
lines changed

.changeset/tiny-jokes-compete.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'firebase': minor
3+
'@firebase/firestore': minor
4+
---
5+
6+
feat(firestore): Support added for the `isType` Pipeline expression.

common/api-review/firestore-lite-pipelines.api.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,8 @@ export abstract class Expression {
502502
/* Excluded from this release type: _readUserData */
503503
isError(): BooleanExpression;
504504
/* Excluded from this release type: _readUserData */
505+
isType(type: Type): BooleanExpression;
506+
/* Excluded from this release type: _readUserData */
505507
join(delimiterExpression: Expression): Expression;
506508
/* Excluded from this release type: _readUserData */
507509
join(delimiter: string): Expression;
@@ -771,6 +773,12 @@ export function isAbsent(field: string): BooleanExpression;
771773
// @beta
772774
export function isError(value: Expression): BooleanExpression;
773775

776+
// @beta
777+
export function isType(fieldName: string, type: Type): BooleanExpression;
778+
779+
// @beta
780+
export function isType(expression: Expression, type: Type): BooleanExpression;
781+
774782
// @beta
775783
export function join(arrayFieldName: string, delimiter: string): Expression;
776784

@@ -1376,6 +1384,9 @@ export function trunc(fieldName: string, decimalPlaces: number | Expression): Fu
13761384
// @beta
13771385
export function trunc(expression: Expression, decimalPlaces: number | Expression): FunctionExpression;
13781386

1387+
// @beta
1388+
export type Type = 'null' | 'array' | 'boolean' | 'bytes' | 'timestamp' | 'geo_point' | 'number' | 'int32' | 'int64' | 'float64' | 'decimal128' | 'map' | 'reference' | 'string' | 'vector' | 'max_key' | 'min_key' | 'object_id' | 'regex' | 'request_timestamp';
1389+
13791390
// @beta
13801391
export function type(fieldName: string): FunctionExpression;
13811392

common/api-review/firestore-pipelines.api.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,8 @@ export abstract class Expression {
505505
/* Excluded from this release type: _readUserData */
506506
isError(): BooleanExpression;
507507
/* Excluded from this release type: _readUserData */
508+
isType(type: Type): BooleanExpression;
509+
/* Excluded from this release type: _readUserData */
508510
join(delimiterExpression: Expression): Expression;
509511
/* Excluded from this release type: _readUserData */
510512
join(delimiter: string): Expression;
@@ -774,6 +776,12 @@ export function isAbsent(field: string): BooleanExpression;
774776
// @beta
775777
export function isError(value: Expression): BooleanExpression;
776778

779+
// @beta
780+
export function isType(fieldName: string, type: Type): BooleanExpression;
781+
782+
// @beta
783+
export function isType(expression: Expression, type: Type): BooleanExpression;
784+
777785
// @beta
778786
export function join(arrayFieldName: string, delimiter: string): Expression;
779787

@@ -1413,6 +1421,9 @@ export function trunc(fieldName: string, decimalPlaces: number | Expression): Fu
14131421
// @beta
14141422
export function trunc(expression: Expression, decimalPlaces: number | Expression): FunctionExpression;
14151423

1424+
// @beta
1425+
export type Type = 'null' | 'array' | 'boolean' | 'bytes' | 'timestamp' | 'geo_point' | 'number' | 'int32' | 'int64' | 'float64' | 'decimal128' | 'map' | 'reference' | 'string' | 'vector' | 'max_key' | 'min_key' | 'object_id' | 'regex' | 'request_timestamp';
1426+
14161427
// @beta
14171428
export function type(fieldName: string): FunctionExpression;
14181429

docs-devsite/firestore_lite_pipelines.expression.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ field("optional_field").ifAbsent(field('default_field'))
101101
| [ifError(catchValue)](./firestore_lite_pipelines.expression.md#expressioniferror) | | <b><i>(Public Preview)</i></b> Creates an expression that returns the <code>catch</code> argument if there is an error, else return the result of this expression. |
102102
| [isAbsent()](./firestore_lite_pipelines.expression.md#expressionisabsent) | | <b><i>(Public Preview)</i></b> Creates an expression that returns <code>true</code> if the result of this expression is absent. Otherwise, returns <code>false</code> even if the value is <code>null</code>. |
103103
| [isError()](./firestore_lite_pipelines.expression.md#expressioniserror) | | <b><i>(Public Preview)</i></b> Creates an expression that checks if a given expression produces an error. |
104+
| [isType(type)](./firestore_lite_pipelines.expression.md#expressionistype) | | <b><i>(Public Preview)</i></b> Creates an expression that checks if the result of this expression is of the given type. |
104105
| [join(delimiterExpression)](./firestore_lite_pipelines.expression.md#expressionjoin) | | <b><i>(Public Preview)</i></b> Creates an expression that joins the elements of an array into a string. |
105106
| [join(delimiter)](./firestore_lite_pipelines.expression.md#expressionjoin) | | <b><i>(Public Preview)</i></b> Creates an expression that joins the elements of an array field into a string. |
106107
| [last()](./firestore_lite_pipelines.expression.md#expressionlast) | | <b><i>(Public Preview)</i></b> Creates an aggregation that finds the last value of an expression across multiple stage inputs. |
@@ -1977,6 +1978,42 @@ field("title").arrayContains(1).isError();
19771978

19781979
```
19791980

1981+
## Expression.isType()
1982+
1983+
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
1984+
>
1985+
1986+
Creates an expression that checks if the result of this expression is of the given type.
1987+
1988+
Null or undefined fields evaluate to skip/error. Use `ifAbsent()` / `isAbsent()` to evaluate missing data.
1989+
1990+
<b>Signature:</b>
1991+
1992+
```typescript
1993+
isType(type: Type): BooleanExpression;
1994+
```
1995+
1996+
#### Parameters
1997+
1998+
| Parameter | Type | Description |
1999+
| --- | --- | --- |
2000+
| type | [Type](./firestore_lite_pipelines.md#type) | The type to check for. |
2001+
2002+
<b>Returns:</b>
2003+
2004+
[BooleanExpression](./firestore_lite_pipelines.booleanexpression.md#booleanexpression_class)
2005+
2006+
A new `BooleanExpression` that evaluates to true if the expression's result is of the given type, false otherwise.
2007+
2008+
### Example
2009+
2010+
2011+
```typescript
2012+
// Check if the 'price' field is specifically an integer (not just 'number')
2013+
field('price').isType('int64');
2014+
2015+
```
2016+
19802017
## Expression.join()
19812018

19822019
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
@@ -4463,6 +4500,8 @@ field("rating").trunc(constant(2));
44634500
44644501
Creates an expression that returns the data type of this expression's result, as a string.
44654502
4503+
This is evaluated on the backend. This means: 1. Generic typed elements (like `array<string>`<!-- -->) evaluate strictly to the primitive `'array'`<!-- -->. 2. Any custom `FirestoreDataConverter` mappings are ignored. 3. For numeric values, the backend does not yield the JavaScript `"number"` type; it evaluates precisely as `"int64"` or `"float64"`<!-- -->. 4. For date or timestamp objects, the backend evaluates to `"timestamp"`<!-- -->.
4504+
44664505
<b>Signature:</b>
44674506
44684507
```typescript

docs-devsite/firestore_lite_pipelines.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ https://github.com/firebase/firebase-js-sdk
8787
| [first(expression)](./firestore_lite_pipelines.md#first_1138a27) | <b><i>(Public Preview)</i></b> Creates an aggregation that finds the first value of an expression across multiple stage inputs. |
8888
| [greaterThan(expression, value)](./firestore_lite_pipelines.md#greaterthan_01df3cf) | <b><i>(Public Preview)</i></b> Creates an expression that checks if an expression is greater than a constant value. |
8989
| [greaterThanOrEqual(expression, value)](./firestore_lite_pipelines.md#greaterthanorequal_01df3cf) | <b><i>(Public Preview)</i></b> Creates an expression that checks if an expression is greater than or equal to a constant value. |
90+
| [isType(expression, type)](./firestore_lite_pipelines.md#istype_27398ce) | <b><i>(Public Preview)</i></b> Creates an expression that checks if the result of an expression is of the given type. |
9091
| [last(expression)](./firestore_lite_pipelines.md#last_1138a27) | <b><i>(Public Preview)</i></b> Creates an aggregation that finds the last value of an expression across multiple stage inputs. |
9192
| [length\_2(expression)](./firestore_lite_pipelines.md#length_2_1138a27) | <b><i>(Public Preview)</i></b> Creates an expression that calculates the length of a string, array, map, vector, or bytes. |
9293
| [lessThan(expression, value)](./firestore_lite_pipelines.md#lessthan_01df3cf) | <b><i>(Public Preview)</i></b> Creates an expression that checks if an expression is less than a constant value. |
@@ -165,6 +166,7 @@ https://github.com/firebase/firebase-js-sdk
165166
| [greaterThan(fieldName, value)](./firestore_lite_pipelines.md#greaterthan_65e2f32) | <b><i>(Public Preview)</i></b> Creates an expression that checks if a field's value is greater than a constant value. |
166167
| [greaterThanOrEqual(fieldName, value)](./firestore_lite_pipelines.md#greaterthanorequal_2e16acb) | <b><i>(Public Preview)</i></b> Creates an expression that checks if a field's value is greater than or equal to an expression. |
167168
| [greaterThanOrEqual(fieldName, value)](./firestore_lite_pipelines.md#greaterthanorequal_65e2f32) | <b><i>(Public Preview)</i></b> Creates an expression that checks if a field's value is greater than or equal to a constant value. |
169+
| [isType(fieldName, type)](./firestore_lite_pipelines.md#istype_5da287e) | <b><i>(Public Preview)</i></b> Creates an expression that checks if the value in the specified field is of the given type. |
168170
| [last(fieldName)](./firestore_lite_pipelines.md#last_e5b0480) | <b><i>(Public Preview)</i></b> Creates an aggregation that finds the last value of a field across multiple stage inputs. |
169171
| [length\_2(fieldName)](./firestore_lite_pipelines.md#length_2_e5b0480) | <b><i>(Public Preview)</i></b> Creates an expression that calculates the length of a string, array, map, vector, or bytes. |
170172
| [lessThan(fieldName, expression)](./firestore_lite_pipelines.md#lessthan_1e91657) | <b><i>(Public Preview)</i></b> Creates an expression that checks if a field's value is less than an expression. |
@@ -405,6 +407,7 @@ https://github.com/firebase/firebase-js-sdk
405407
| [SetOptions](./firestore_lite_pipelines.md#setoptions) | An options object that configures the behavior of [setDoc()](./firestore_lite.md#setdoc_ee215ad)<!-- -->, and calls. These calls can be configured to perform granular merges instead of overwriting the target documents in their entirety by providing a <code>SetOptions</code> with <code>merge: true</code>. |
406408
| [SortStageOptions](./firestore_lite_pipelines.md#sortstageoptions) | <b><i>(Public Preview)</i></b> Options defining how a SortStage is evaluated. See [Pipeline.sort()](./firestore_pipelines.pipeline.md#pipelinesort)<!-- -->. |
407409
| [TimeGranularity](./firestore_lite_pipelines.md#timegranularity) | <b><i>(Public Preview)</i></b> Specify time granularity for expressions. |
410+
| [Type](./firestore_lite_pipelines.md#type) | <b><i>(Public Preview)</i></b> An enumeration of the different types generated by the Firestore backend.<ul> <li>Numerics evaluate directly to backend representation (<code>int64</code> or <code>float64</code>), not JS <code>number</code>.</li> <li>JavaScript <code>Date</code> and firestore <code>Timestamp</code> objects strictly evaluate to <code>'timestamp'</code>.</li> <li>Advanced configurations parsing backend types (such as <code>decimal128</code>, <code>max_key</code> or <code>min_key</code> from BSON) are also incorporated in this union string type. Note that <code>decimal128</code> is a backend-only numeric type that the JavaScript SDK cannot create natively, but can be evaluated in pipelines.</li> </ul> |
408411
| [UnionStageOptions](./firestore_lite_pipelines.md#unionstageoptions) | <b><i>(Public Preview)</i></b> Options defining how a UnionStage is evaluated. See [Pipeline.union()](./firestore_pipelines.pipeline.md#pipelineunion)<!-- -->. |
409412
| [UnnestStageOptions](./firestore_lite_pipelines.md#unneststageoptions) | <b><i>(Public Preview)</i></b> Represents the specific options available for configuring an <code>UnnestStage</code> within a pipeline. |
410413
| [WhereStageOptions](./firestore_lite_pipelines.md#wherestageoptions) | <b><i>(Public Preview)</i></b> Options defining how a WhereStage is evaluated. See [Pipeline.where()](./firestore_pipelines.pipeline.md#pipelinewhere)<!-- -->. |
@@ -2399,6 +2402,43 @@ greaterThanOrEqual(field("quantity"), 10);
23992402

24002403
```
24012404

2405+
### isType(expression, type) {:#istype_27398ce}
2406+
2407+
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
2408+
>
2409+
2410+
Creates an expression that checks if the result of an expression is of the given type.
2411+
2412+
Null or undefined fields evaluate to skip/error. Use `ifAbsent()` / `isAbsent()` to evaluate missing data.
2413+
2414+
<b>Signature:</b>
2415+
2416+
```typescript
2417+
export declare function isType(expression: Expression, type: Type): BooleanExpression;
2418+
```
2419+
2420+
#### Parameters
2421+
2422+
| Parameter | Type | Description |
2423+
| --- | --- | --- |
2424+
| expression | [Expression](./firestore_lite_pipelines.expression.md#expression_class) | The expression to check. |
2425+
| type | [Type](./firestore_lite_pipelines.md#type) | The type to check for. |
2426+
2427+
<b>Returns:</b>
2428+
2429+
[BooleanExpression](./firestore_lite_pipelines.booleanexpression.md#booleanexpression_class)
2430+
2431+
A new `BooleanExpression` that evaluates to true if the expression's result is of the given type, false otherwise.
2432+
2433+
### Example
2434+
2435+
2436+
```typescript
2437+
// Check if the result of a calculation is a number
2438+
isType(add('count', 1), 'number')
2439+
2440+
```
2441+
24022442
### last(expression) {:#last_1138a27}
24032443

24042444
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
@@ -5014,6 +5054,43 @@ greaterThanOrEqual("score", 80);
50145054

50155055
```
50165056
5057+
### isType(fieldName, type) {:#istype_5da287e}
5058+
5059+
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
5060+
>
5061+
5062+
Creates an expression that checks if the value in the specified field is of the given type.
5063+
5064+
Null or undefined fields evaluate to skip/error. Use `ifAbsent()` / `isAbsent()` to evaluate missing data.
5065+
5066+
<b>Signature:</b>
5067+
5068+
```typescript
5069+
export declare function isType(fieldName: string, type: Type): BooleanExpression;
5070+
```
5071+
5072+
#### Parameters
5073+
5074+
| Parameter | Type | Description |
5075+
| --- | --- | --- |
5076+
| fieldName | string | The name of the field to check. |
5077+
| type | [Type](./firestore_lite_pipelines.md#type) | The type to check for. |
5078+
5079+
<b>Returns:</b>
5080+
5081+
[BooleanExpression](./firestore_lite_pipelines.booleanexpression.md#booleanexpression_class)
5082+
5083+
A new `BooleanExpression` that evaluates to true if the field's value is of the given type, false otherwise.
5084+
5085+
### Example
5086+
5087+
5088+
```typescript
5089+
// Check if the 'price' field is a floating point number (evaluating to true inside pipeline conditionals)
5090+
isType('price', 'float64');
5091+
5092+
```
5093+
50175094
### last(fieldName) {:#last_e5b0480}
50185095
50195096
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
@@ -7242,6 +7319,8 @@ trunc("rating", 2);
72427319
72437320
Creates an expression that returns the data type of the data in the specified field.
72447321
7322+
String inputs passed iteratively to this global function act as `field()` path lookups. If you wish to pass a string literal value, it must be wrapped: `type(constant("my_string"))`<!-- -->.
7323+
72457324
<b>Signature:</b>
72467325
72477326
```typescript
@@ -10728,6 +10807,21 @@ Specify time granularity for expressions.
1072810807
export declare type TimeGranularity = 'microsecond' | 'millisecond' | 'second' | 'minute' | 'hour' | 'day' | 'week' | 'week(monday)' | 'week(tuesday)' | 'week(wednesday)' | 'week(thursday)' | 'week(friday)' | 'week(saturday)' | 'week(sunday)' | 'isoWeek' | 'month' | 'quarter' | 'year' | 'isoYear';
1072910808
```
1073010809
10810+
## Type
10811+
10812+
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
10813+
>
10814+
10815+
An enumeration of the different types generated by the Firestore backend.
10816+
10817+
<ul> <li>Numerics evaluate directly to backend representation (`int64` or `float64`<!-- -->), not JS `number`<!-- -->.</li> <li>JavaScript `Date` and firestore `Timestamp` objects strictly evaluate to `'timestamp'`<!-- -->.</li> <li>Advanced configurations parsing backend types (such as `decimal128`<!-- -->, `max_key` or `min_key` from BSON) are also incorporated in this union string type. Note that `decimal128` is a backend-only numeric type that the JavaScript SDK cannot create natively, but can be evaluated in pipelines.</li> </ul>
10818+
10819+
<b>Signature:</b>
10820+
10821+
```typescript
10822+
export declare type Type = 'null' | 'array' | 'boolean' | 'bytes' | 'timestamp' | 'geo_point' | 'number' | 'int32' | 'int64' | 'float64' | 'decimal128' | 'map' | 'reference' | 'string' | 'vector' | 'max_key' | 'min_key' | 'object_id' | 'regex' | 'request_timestamp';
10823+
```
10824+
1073110825
## UnionStageOptions
1073210826
1073310827
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.

docs-devsite/firestore_pipelines.expression.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ field("optional_field").ifAbsent(field('default_field'))
101101
| [ifError(catchValue)](./firestore_pipelines.expression.md#expressioniferror) | | <b><i>(Public Preview)</i></b> Creates an expression that returns the <code>catch</code> argument if there is an error, else return the result of this expression. |
102102
| [isAbsent()](./firestore_pipelines.expression.md#expressionisabsent) | | <b><i>(Public Preview)</i></b> Creates an expression that returns <code>true</code> if the result of this expression is absent. Otherwise, returns <code>false</code> even if the value is <code>null</code>. |
103103
| [isError()](./firestore_pipelines.expression.md#expressioniserror) | | <b><i>(Public Preview)</i></b> Creates an expression that checks if a given expression produces an error. |
104+
| [isType(type)](./firestore_pipelines.expression.md#expressionistype) | | <b><i>(Public Preview)</i></b> Creates an expression that checks if the result of this expression is of the given type. |
104105
| [join(delimiterExpression)](./firestore_pipelines.expression.md#expressionjoin) | | <b><i>(Public Preview)</i></b> Creates an expression that joins the elements of an array into a string. |
105106
| [join(delimiter)](./firestore_pipelines.expression.md#expressionjoin) | | <b><i>(Public Preview)</i></b> Creates an expression that joins the elements of an array field into a string. |
106107
| [last()](./firestore_pipelines.expression.md#expressionlast) | | <b><i>(Public Preview)</i></b> Creates an aggregation that finds the last value of an expression across multiple stage inputs. |
@@ -1977,6 +1978,42 @@ field("title").arrayContains(1).isError();
19771978

19781979
```
19791980

1981+
## Expression.isType()
1982+
1983+
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
1984+
>
1985+
1986+
Creates an expression that checks if the result of this expression is of the given type.
1987+
1988+
Null or undefined fields evaluate to skip/error. Use `ifAbsent()` / `isAbsent()` to evaluate missing data.
1989+
1990+
<b>Signature:</b>
1991+
1992+
```typescript
1993+
isType(type: Type): BooleanExpression;
1994+
```
1995+
1996+
#### Parameters
1997+
1998+
| Parameter | Type | Description |
1999+
| --- | --- | --- |
2000+
| type | [Type](./firestore_pipelines.md#type) | The type to check for. |
2001+
2002+
<b>Returns:</b>
2003+
2004+
[BooleanExpression](./firestore_pipelines.booleanexpression.md#booleanexpression_class)
2005+
2006+
A new `BooleanExpression` that evaluates to true if the expression's result is of the given type, false otherwise.
2007+
2008+
### Example
2009+
2010+
2011+
```typescript
2012+
// Check if the 'price' field is specifically an integer (not just 'number')
2013+
field('price').isType('int64');
2014+
2015+
```
2016+
19802017
## Expression.join()
19812018

19822019
> This API is provided as a preview for developers and may change based on feedback that we receive. Do not use this API in a production environment.
@@ -4463,6 +4500,8 @@ field("rating").trunc(constant(2));
44634500
44644501
Creates an expression that returns the data type of this expression's result, as a string.
44654502
4503+
This is evaluated on the backend. This means: 1. Generic typed elements (like `array<string>`<!-- -->) evaluate strictly to the primitive `'array'`<!-- -->. 2. Any custom `FirestoreDataConverter` mappings are ignored. 3. For numeric values, the backend does not yield the JavaScript `"number"` type; it evaluates precisely as `"int64"` or `"float64"`<!-- -->. 4. For date or timestamp objects, the backend evaluates to `"timestamp"`<!-- -->.
4504+
44664505
<b>Signature:</b>
44674506
44684507
```typescript

0 commit comments

Comments
 (0)