Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions .changeset/nine-toes-explain.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@firebase/firestore": minor
"firebase": minor
---

Added minimum and maximum FieldValue operations
6 changes: 6 additions & 0 deletions common/api-review/firestore-lite.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,12 @@ export function limitToLast(limit: number): QueryLimitConstraint;

export { LogLevel }

// @public
export function maximum(n: number): FieldValue;

// @public
export function minimum(n: number): FieldValue;

// @public
export type NestedUpdateFields<T extends Record<string, unknown>> = UnionToIntersection<{
[K in keyof T & string]: ChildUpdateFields<K, T[K]>;
Expand Down
6 changes: 6 additions & 0 deletions common/api-review/firestore.api.md
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,9 @@ export interface LoadBundleTaskProgress {

export { LogLevel }

// @public
export function maximum(n: number): FieldValue;

// @public
export interface MemoryCacheSettings {
garbageCollector?: MemoryGarbageCollector;
Expand Down Expand Up @@ -425,6 +428,9 @@ export function memoryLruGarbageCollector(settings?: {
cacheSizeBytes?: number;
}): MemoryLruGarbageCollector;

// @public
export function minimum(n: number): FieldValue;

// @public
export function namedQuery(firestore: Firestore, name: string): Promise<Query | null>;

Expand Down
46 changes: 46 additions & 0 deletions docs-devsite/firestore_.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ https://github.com/firebase/firebase-js-sdk
| [setLogLevel(logLevel)](./firestore_.md#setloglevel_d02fda2) | Sets the verbosity of Cloud Firestore logs (debug, error, or silent). |
| <b>function(n, ...)</b> |
| [increment(n)](./firestore_.md#increment_5685735) | Returns a special value that can be used with [setDoc()](./firestore_lite.md#setdoc_ee215ad) or [updateDoc()](./firestore_lite.md#updatedoc_51a65e3) that tells the server to increment the field's current value by the given value.<!-- -->If either the operand or the current field value uses floating point precision, all arithmetic follows IEEE 754 semantics. If both values are integers, values outside of JavaScript's safe number range (<code>Number.MIN_SAFE_INTEGER</code> to <code>Number.MAX_SAFE_INTEGER</code>) are also subject to precision loss. Furthermore, once processed by the Firestore backend, all integer operations are capped between -2^63 and 2^63-1.<!-- -->If the current field value is not of type <code>number</code>, or if the field does not yet exist, the transformation sets the field to the given value. |
| [maximum(n)](./firestore_.md#maximum_5685735) | Returns a special value that can be used with [setDoc()](./firestore_lite.md#setdoc_ee215ad) or [updateDoc()](./firestore_lite.md#updatedoc_51a65e3) that tells the server to set the field to the numeric maximum of the field's current and the given value. |
| [minimum(n)](./firestore_.md#minimum_5685735) | Returns a special value that can be used with [setDoc()](./firestore_lite.md#setdoc_ee215ad) or [updateDoc()](./firestore_lite.md#updatedoc_51a65e3) that tells the server to set the field to the numeric minimum of the field's current and the given value. |
| <b>function(query, ...)</b> |
| [getAggregateFromServer(query, aggregateSpec)](./firestore_.md#getaggregatefromserver_2073a74) | Calculates the specified aggregations over the documents in the result set of the given query without actually downloading the documents.<!-- -->Using this function to perform aggregations is efficient because only the final aggregation values, not the documents' data, are downloaded. This function can perform aggregations of the documents in cases where the result set is prohibitively large to download entirely (thousands of documents).<!-- -->The result received from the server is presented, unaltered, without considering any local state. That is, documents in the local cache are not taken into consideration, neither are local modifications not yet synchronized with the server. Previously-downloaded results, if any, are not used. Every invocation of this function necessarily involves a round trip to the server. |
| [getCountFromServer(query)](./firestore_.md#getcountfromserver_4e56953) | Calculates the number of documents in the result set of the given query without actually downloading the documents.<!-- -->Using this function to count the documents is efficient because only the final count, not the documents' data, is downloaded. This function can count the documents in cases where the result set is prohibitively large to download entirely (thousands of documents).<!-- -->The result received from the server is presented, unaltered, without considering any local state. That is, documents in the local cache are not taken into consideration, neither are local modifications not yet synchronized with the server. Previously-downloaded results, if any, are not used. Every invocation of this function necessarily involves a round trip to the server. |
Expand Down Expand Up @@ -1842,6 +1844,50 @@ export declare function increment(n: number): FieldValue;

The `FieldValue` sentinel for use in a call to `setDoc()` or `updateDoc()`

### maximum(n) {:#maximum_5685735}

Returns a special value that can be used with [setDoc()](./firestore_lite.md#setdoc_ee215ad) or [updateDoc()](./firestore_lite.md#updatedoc_51a65e3) that tells the server to set the field to the numeric maximum of the field's current and the given value.

<b>Signature:</b>

```typescript
export declare function maximum(n: number): FieldValue;
```

#### Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| n | number | The value to compare to the existing field value. |

<b>Returns:</b>

[FieldValue](./firestore_.fieldvalue.md#fieldvalue_class)

The `FieldValue` sentinel for use in a call to `setDoc()` or `updateDoc()`

### minimum(n) {:#minimum_5685735}

Returns a special value that can be used with [setDoc()](./firestore_lite.md#setdoc_ee215ad) or [updateDoc()](./firestore_lite.md#updatedoc_51a65e3) that tells the server to set the field to the numeric minimum of the field's current and the given value.

<b>Signature:</b>

```typescript
export declare function minimum(n: number): FieldValue;
```

#### Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| n | number | The value to compare to the existing field value. |

<b>Returns:</b>

[FieldValue](./firestore_.fieldvalue.md#fieldvalue_class)

The `FieldValue` sentinel for use in a call to `setDoc()` or `updateDoc()`

## function(query, ...)

### getAggregateFromServer(query, aggregateSpec) {:#getaggregatefromserver_2073a74}
Expand Down
46 changes: 46 additions & 0 deletions docs-devsite/firestore_lite.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ https://github.com/firebase/firebase-js-sdk
| [setLogLevel(logLevel)](./firestore_lite.md#setloglevel_d02fda2) | Sets the verbosity of Cloud Firestore logs (debug, error, or silent). |
| <b>function(n, ...)</b> |
| [increment(n)](./firestore_lite.md#increment_5685735) | Returns a special value that can be used with [setDoc()](./firestore_lite.md#setdoc_ee215ad) or [updateDoc()](./firestore_lite.md#updatedoc_51a65e3) that tells the server to increment the field's current value by the given value.<!-- -->If either the operand or the current field value uses floating point precision, all arithmetic follows IEEE 754 semantics. If both values are integers, values outside of JavaScript's safe number range (<code>Number.MIN_SAFE_INTEGER</code> to <code>Number.MAX_SAFE_INTEGER</code>) are also subject to precision loss. Furthermore, once processed by the Firestore backend, all integer operations are capped between -2^63 and 2^63-1.<!-- -->If the current field value is not of type <code>number</code>, or if the field does not yet exist, the transformation sets the field to the given value. |
| [maximum(n)](./firestore_lite.md#maximum_5685735) | Returns a special value that can be used with [setDoc()](./firestore_lite.md#setdoc_ee215ad) or [updateDoc()](./firestore_lite.md#updatedoc_51a65e3) that tells the server to set the field to the numeric maximum of the field's current and the given value. |
| [minimum(n)](./firestore_lite.md#minimum_5685735) | Returns a special value that can be used with [setDoc()](./firestore_lite.md#setdoc_ee215ad) or [updateDoc()](./firestore_lite.md#updatedoc_51a65e3) that tells the server to set the field to the numeric minimum of the field's current and the given value. |
| <b>function(query, ...)</b> |
| [getAggregate(query, aggregateSpec)](./firestore_lite.md#getaggregate_2073a74) | Calculates the specified aggregations over the documents in the result set of the given query without actually downloading the documents.<!-- -->Using this function to perform aggregations is efficient because only the final aggregation values, not the documents' data, are downloaded. This function can perform aggregations of the documents in cases where the result set is prohibitively large to download entirely (thousands of documents). |
| [getCount(query)](./firestore_lite.md#getcount_4e56953) | Calculates the number of documents in the result set of the given query without actually downloading the documents.<!-- -->Using this function to count the documents is efficient because only the final count, not the documents' data, is downloaded. This function can count the documents in cases where the result set is prohibitively large to download entirely (thousands of documents). |
Expand Down Expand Up @@ -981,6 +983,50 @@ export declare function increment(n: number): FieldValue;

The `FieldValue` sentinel for use in a call to `setDoc()` or `updateDoc()`

### maximum(n) {:#maximum_5685735}

Returns a special value that can be used with [setDoc()](./firestore_lite.md#setdoc_ee215ad) or [updateDoc()](./firestore_lite.md#updatedoc_51a65e3) that tells the server to set the field to the numeric maximum of the field's current and the given value.

<b>Signature:</b>

```typescript
export declare function maximum(n: number): FieldValue;
```

#### Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| n | number | The value to compare to the existing field value. |

<b>Returns:</b>

[FieldValue](./firestore_lite.fieldvalue.md#fieldvalue_class)

The `FieldValue` sentinel for use in a call to `setDoc()` or `updateDoc()`

### minimum(n) {:#minimum_5685735}

Returns a special value that can be used with [setDoc()](./firestore_lite.md#setdoc_ee215ad) or [updateDoc()](./firestore_lite.md#updatedoc_51a65e3) that tells the server to set the field to the numeric minimum of the field's current and the given value.

<b>Signature:</b>

```typescript
export declare function minimum(n: number): FieldValue;
```

#### Parameters

| Parameter | Type | Description |
| --- | --- | --- |
| n | number | The value to compare to the existing field value. |

<b>Returns:</b>

[FieldValue](./firestore_lite.fieldvalue.md#fieldvalue_class)

The `FieldValue` sentinel for use in a call to `setDoc()` or `updateDoc()`

## function(query, ...)

### getAggregate(query, aggregateSpec) {:#getaggregate_2073a74}
Expand Down
2 changes: 2 additions & 0 deletions packages/firestore/lite/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@ export { FieldValue } from '../src/lite-api/field_value';

export {
increment,
minimum,
maximum,
arrayRemove,
arrayUnion,
serverTimestamp,
Expand Down
4 changes: 3 additions & 1 deletion packages/firestore/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,9 @@ export {
deleteField,
increment,
serverTimestamp,
vector
vector,
minimum,
maximum
} from './api/field_value_impl';

export { VectorValue } from './lite-api/vector_value';
Expand Down
4 changes: 3 additions & 1 deletion packages/firestore/src/api/field_value_impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,7 @@ export {
arrayUnion,
serverTimestamp,
deleteField,
vector
vector,
minimum,
maximum
} from '../lite-api/field_value_impl';
28 changes: 28 additions & 0 deletions packages/firestore/src/lite-api/field_value_impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import {
ArrayUnionFieldValueImpl,
DeleteFieldValueImpl,
NumericIncrementFieldValueImpl,
NumericMaximumFieldValueImpl,
NumericMinimumFieldValueImpl,
ServerTimestampFieldValueImpl
} from './user_data_reader';
import { VectorValue } from './vector_value';
Expand Down Expand Up @@ -99,6 +101,32 @@ export function increment(n: number): FieldValue {
return new NumericIncrementFieldValueImpl('increment', n);
}

/**
* Returns a special value that can be used with {@link @firebase/firestore/lite#(setDoc:1)} or {@link
* @firebase/firestore/lite#(updateDoc:1)} that tells the server to set the field to the numeric minimum of the
* field's current and the given value.
*
* @param n - The value to compare to the existing field value.
* @returns The `FieldValue` sentinel for use in a call to `setDoc()` or
* `updateDoc()`
*/
export function minimum(n: number): FieldValue {
return new NumericMinimumFieldValueImpl('minimum', n);
}

/**
* Returns a special value that can be used with {@link @firebase/firestore/lite#(setDoc:1)} or {@link
* @firebase/firestore/lite#(updateDoc:1)} that tells the server to set the field to the numeric maximum of the
* field's current and the given value.
*
* @param n - The value to compare to the existing field value.
* @returns The `FieldValue` sentinel for use in a call to `setDoc()` or
* `updateDoc()`
*/
export function maximum(n: number): FieldValue {
return new NumericMaximumFieldValueImpl('maximum', n);
}

/**
* Creates a new `VectorValue` constructed with a copy of the given array of numbers.
*
Expand Down
49 changes: 48 additions & 1 deletion packages/firestore/src/lite-api/user_data_reader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ import {
ArrayRemoveTransformOperation,
ArrayUnionTransformOperation,
NumericIncrementTransformOperation,
NumericMaximumTransformOperation,
NumericMinimumTransformOperation,
ServerTimestampTransform
} from '../model/transform_operation';
import {
Expand Down Expand Up @@ -556,7 +558,52 @@ export class NumericIncrementFieldValueImpl extends FieldValue {
isEqual(other: FieldValue): boolean {
return (
other instanceof NumericIncrementFieldValueImpl &&
this._operand === other._operand
(this._operand === other._operand ||
(Number.isNaN(this._operand) && Number.isNaN(other._operand)))
);
}
}

export class NumericMinimumFieldValueImpl extends FieldValue {
constructor(methodName: string, private readonly _operand: number) {
super(methodName);
}

_toFieldTransform(context: ParseContextImpl): FieldTransform {
const numericMinimum = new NumericMinimumTransformOperation(
context.serializer,
toNumber(context.serializer, this._operand)
);
return new FieldTransform(context.path!, numericMinimum);
}

isEqual(other: FieldValue): boolean {
return (
other instanceof NumericMinimumFieldValueImpl &&
(this._operand === other._operand ||
(Number.isNaN(this._operand) && Number.isNaN(other._operand)))
);
}
}

export class NumericMaximumFieldValueImpl extends FieldValue {
constructor(methodName: string, private readonly _operand: number) {
super(methodName);
}

_toFieldTransform(context: ParseContextImpl): FieldTransform {
const numericMaximum = new NumericMaximumTransformOperation(
context.serializer,
toNumber(context.serializer, this._operand)
);
return new FieldTransform(context.path!, numericMaximum);
}

isEqual(other: FieldValue): boolean {
return (
other instanceof NumericMaximumFieldValueImpl &&
(this._operand === other._operand ||
(Number.isNaN(this._operand) && Number.isNaN(other._operand)))
);
}
}
Expand Down
Loading
Loading