Skip to content

Commit

Permalink
Firestore: FirestoreDataConverter doc and test improvements (#7932)
Browse files Browse the repository at this point in the history
  • Loading branch information
dconeybe authored Jan 17, 2024
1 parent 991fa27 commit e9869c4
Show file tree
Hide file tree
Showing 7 changed files with 137 additions and 10 deletions.
8 changes: 6 additions & 2 deletions docs-devsite/firestore_.firestoredataconverter.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Converter used by `withConverter()` to transform user objects of type `AppModelT

Using the converter allows you to specify generic type arguments when storing and retrieving objects from Firestore.

In this context, an "AppModel" is a class that is used in an application to package together related information and functionality. Such a class could, for example, have properties with complex, nested data types, properties used for memoization, properties of types not supported by Firestore (such as `symbol` and `bigint`<!-- -->), and helper functions that perform compound operations. Such classes are not suitable and/or possible to store into a Firestore database. Instead, instances of such classes need to be converted to "plain old JavaScript objects" (POJOs) with exclusively primitive properties, potentially nested inside other POJOs or arrays of POJOs. In this context, this type is referred to as the "DbModel" and would be an object suitable for persisting into Firestore. For convenience, applications can implement `FirestoreDataConverter` and register the converter with Firestore objects, such as `DocumentReference` or `Query`<!-- -->, to automatically convert `AppModel` to `DbModel` when storing into Firestore, and convert `DbModel` to `AppModel` when retrieving from Firestore.

<b>Signature:</b>

```typescript
Expand All @@ -24,15 +26,17 @@ export declare interface FirestoreDataConverter<AppModelType, DbModelType extend

| Method | Description |
| --- | --- |
| [fromFirestore(snapshot, options)](./firestore_.firestoredataconverter.md#firestoredataconverterfromfirestore) | Called by the Firestore SDK to convert Firestore data into an object of type <code>AppModelType</code>. You can access your data by calling: <code>snapshot.data(options)</code>.<!-- -->Generally, the data returned from <code>snapshot.data()</code> can be cast to <code>DbModelType</code>; however, this is not guaranteed as writes to the database may have occurred without a type converter enforcing this specific layout. |
| [fromFirestore(snapshot, options)](./firestore_.firestoredataconverter.md#firestoredataconverterfromfirestore) | Called by the Firestore SDK to convert Firestore data into an object of type <code>AppModelType</code>. You can access your data by calling: <code>snapshot.data(options)</code>.<!-- -->Generally, the data returned from <code>snapshot.data()</code> can be cast to <code>DbModelType</code>; however, this is not guaranteed because Firestore does not enforce a schema on the database. For example, writes from a previous version of the application or writes from another client that did not use a type converter could have written data with different properties and/or property types. The implementation will need to choose whether to gracefully recover from non-conforming data or throw an error.<!-- -->To override this method, see . |
| [toFirestore(modelObject)](./firestore_.firestoredataconverter.md#firestoredataconvertertofirestore) | Called by the Firestore SDK to convert a custom model object of type <code>AppModelType</code> into a plain JavaScript object (suitable for writing directly to the Firestore database) of type <code>DbModelType</code>. To use <code>set()</code> with <code>merge</code> and <code>mergeFields</code>, <code>toFirestore()</code> must be defined with <code>PartialWithFieldValue&lt;AppModelType&gt;</code>.<!-- -->The <code>WithFieldValue&lt;T&gt;</code> type extends <code>T</code> to also allow FieldValues such as [deleteField()](./firestore_.md#deletefield) to be used as property values. |
| [toFirestore(modelObject, options)](./firestore_.firestoredataconverter.md#firestoredataconvertertofirestore) | Called by the Firestore SDK to convert a custom model object of type <code>AppModelType</code> into a plain JavaScript object (suitable for writing directly to the Firestore database) of type <code>DbModelType</code>. Used with [setDoc()](./firestore_.md#setdoc_ee215ad)<!-- -->, and with <code>merge:true</code> or <code>mergeFields</code>.<!-- -->The <code>PartialWithFieldValue&lt;T&gt;</code> type extends <code>Partial&lt;T&gt;</code> to allow FieldValues such as [arrayUnion()](./firestore_.md#arrayunion_7d853aa) to be used as property values. It also supports nested <code>Partial</code> by allowing nested fields to be omitted. |

## FirestoreDataConverter.fromFirestore()

Called by the Firestore SDK to convert Firestore data into an object of type `AppModelType`<!-- -->. You can access your data by calling: `snapshot.data(options)`<!-- -->.

Generally, the data returned from `snapshot.data()` can be cast to `DbModelType`<!-- -->; however, this is not guaranteed as writes to the database may have occurred without a type converter enforcing this specific layout.
Generally, the data returned from `snapshot.data()` can be cast to `DbModelType`<!-- -->; however, this is not guaranteed because Firestore does not enforce a schema on the database. For example, writes from a previous version of the application or writes from another client that did not use a type converter could have written data with different properties and/or property types. The implementation will need to choose whether to gracefully recover from non-conforming data or throw an error.

To override this method, see .

<b>Signature:</b>

Expand Down
2 changes: 1 addition & 1 deletion docs-devsite/firestore_.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ https://github.com/firebase/firebase-js-sdk
| [DocumentChange](./firestore_.documentchange.md#documentchange_interface) | A <code>DocumentChange</code> represents a change to the documents matching a query. It contains the document affected and the type of change that occurred. |
| [DocumentData](./firestore_.documentdata.md#documentdata_interface) | Document data (for use with [setDoc()](./firestore_lite.md#setdoc_ee215ad)<!-- -->) consists of fields mapped to values. |
| [ExperimentalLongPollingOptions](./firestore_.experimentallongpollingoptions.md#experimentallongpollingoptions_interface) | Options that configure the SDK’s underlying network transport (WebChannel) when long-polling is used.<!-- -->Note: This interface is "experimental" and is subject to change.<!-- -->See <code>FirestoreSettings.experimentalAutoDetectLongPolling</code>, <code>FirestoreSettings.experimentalForceLongPolling</code>, and <code>FirestoreSettings.experimentalLongPollingOptions</code>. |
| [FirestoreDataConverter](./firestore_.firestoredataconverter.md#firestoredataconverter_interface) | Converter used by <code>withConverter()</code> to transform user objects of type <code>AppModelType</code> into Firestore data of type <code>DbModelType</code>.<!-- -->Using the converter allows you to specify generic type arguments when storing and retrieving objects from Firestore. |
| [FirestoreDataConverter](./firestore_.firestoredataconverter.md#firestoredataconverter_interface) | Converter used by <code>withConverter()</code> to transform user objects of type <code>AppModelType</code> into Firestore data of type <code>DbModelType</code>.<!-- -->Using the converter allows you to specify generic type arguments when storing and retrieving objects from Firestore.<!-- -->In this context, an "AppModel" is a class that is used in an application to package together related information and functionality. Such a class could, for example, have properties with complex, nested data types, properties used for memoization, properties of types not supported by Firestore (such as <code>symbol</code> and <code>bigint</code>), and helper functions that perform compound operations. Such classes are not suitable and/or possible to store into a Firestore database. Instead, instances of such classes need to be converted to "plain old JavaScript objects" (POJOs) with exclusively primitive properties, potentially nested inside other POJOs or arrays of POJOs. In this context, this type is referred to as the "DbModel" and would be an object suitable for persisting into Firestore. For convenience, applications can implement <code>FirestoreDataConverter</code> and register the converter with Firestore objects, such as <code>DocumentReference</code> or <code>Query</code>, to automatically convert <code>AppModel</code> to <code>DbModel</code> when storing into Firestore, and convert <code>DbModel</code> to <code>AppModel</code> when retrieving from Firestore. |
| [FirestoreSettings](./firestore_.firestoresettings.md#firestoresettings_interface) | Specifies custom configurations for your Cloud Firestore instance. You must set these before invoking any other methods. |
| [Index](./firestore_.index.md#index_interface) | <b><i>(BETA)</i></b> The SDK definition of a Firestore index. |
| [IndexConfiguration](./firestore_.indexconfiguration.md#indexconfiguration_interface) | <b><i>(BETA)</i></b> A list of Firestore indexes to speed up local query execution.<!-- -->See [JSON Format](https://firebase.google.com/docs/reference/firestore/indexes/#json_format) for a description of the format of the index definition. |
Expand Down
6 changes: 4 additions & 2 deletions docs-devsite/firestore_lite.firestoredataconverter.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Converter used by `withConverter()` to transform user objects of type `AppModelT

Using the converter allows you to specify generic type arguments when storing and retrieving objects from Firestore.

In this context, an "AppModel" is a class that is used in an application to package together related information and functionality. Such a class could, for example, have properties with complex, nested data types, properties used for memoization, properties of types not supported by Firestore (such as `symbol` and `bigint`<!-- -->), and helper functions that perform compound operations. Such classes are not suitable and/or possible to store into a Firestore database. Instead, instances of such classes need to be converted to "plain old JavaScript objects" (POJOs) with exclusively primitive properties, potentially nested inside other POJOs or arrays of POJOs. In this context, this type is referred to as the "DbModel" and would be an object suitable for persisting into Firestore. For convenience, applications can implement `FirestoreDataConverter` and register the converter with Firestore objects, such as `DocumentReference` or `Query`<!-- -->, to automatically convert `AppModel` to `DbModel` when storing into Firestore, and convert `DbModel` to `AppModel` when retrieving from Firestore.

<b>Signature:</b>

```typescript
Expand All @@ -24,15 +26,15 @@ export declare interface FirestoreDataConverter<AppModelType, DbModelType extend

| Method | Description |
| --- | --- |
| [fromFirestore(snapshot)](./firestore_lite.firestoredataconverter.md#firestoredataconverterfromfirestore) | Called by the Firestore SDK to convert Firestore data into an object of type <code>AppModelType</code>. You can access your data by calling: <code>snapshot.data()</code>.<!-- -->Generally, the data returned from <code>snapshot.data()</code> can be cast to <code>DbModelType</code>; however, this is not guaranteed as writes to the database may have occurred without a type converter enforcing this specific layout. |
| [fromFirestore(snapshot)](./firestore_lite.firestoredataconverter.md#firestoredataconverterfromfirestore) | Called by the Firestore SDK to convert Firestore data into an object of type <code>AppModelType</code>. You can access your data by calling: <code>snapshot.data()</code>.<!-- -->Generally, the data returned from <code>snapshot.data()</code> can be cast to <code>DbModelType</code>; however, this is not guaranteed because Firestore does not enforce a schema on the database. For example, writes from a previous version of the application or writes from another client that did not use a type converter could have written data with different properties and/or property types. The implementation will need to choose whether to gracefully recover from non-conforming data or throw an error. |
| [toFirestore(modelObject)](./firestore_lite.firestoredataconverter.md#firestoredataconvertertofirestore) | Called by the Firestore SDK to convert a custom model object of type <code>AppModelType</code> into a plain Javascript object (suitable for writing directly to the Firestore database) of type <code>DbModelType</code>. Used with [setDoc()](./firestore_lite.md#setdoc_ee215ad)<!-- -->, and .<!-- -->The <code>WithFieldValue&lt;T&gt;</code> type extends <code>T</code> to also allow FieldValues such as [deleteField()](./firestore_.md#deletefield) to be used as property values. |
| [toFirestore(modelObject, options)](./firestore_lite.firestoredataconverter.md#firestoredataconvertertofirestore) | Called by the Firestore SDK to convert a custom model object of type <code>AppModelType</code> into a plain Javascript object (suitable for writing directly to the Firestore database) of type <code>DbModelType</code>. Used with [setDoc()](./firestore_lite.md#setdoc_ee215ad)<!-- -->, and with <code>merge:true</code> or <code>mergeFields</code>.<!-- -->The <code>PartialWithFieldValue&lt;T&gt;</code> type extends <code>Partial&lt;T&gt;</code> to allow FieldValues such as [arrayUnion()](./firestore_.md#arrayunion_7d853aa) to be used as property values. It also supports nested <code>Partial</code> by allowing nested fields to be omitted. |

## FirestoreDataConverter.fromFirestore()

Called by the Firestore SDK to convert Firestore data into an object of type `AppModelType`<!-- -->. You can access your data by calling: `snapshot.data()`<!-- -->.

Generally, the data returned from `snapshot.data()` can be cast to `DbModelType`<!-- -->; however, this is not guaranteed as writes to the database may have occurred without a type converter enforcing this specific layout.
Generally, the data returned from `snapshot.data()` can be cast to `DbModelType`<!-- -->; however, this is not guaranteed because Firestore does not enforce a schema on the database. For example, writes from a previous version of the application or writes from another client that did not use a type converter could have written data with different properties and/or property types. The implementation will need to choose whether to gracefully recover from non-conforming data or throw an error.

<b>Signature:</b>

Expand Down
2 changes: 1 addition & 1 deletion docs-devsite/firestore_lite.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ https://github.com/firebase/firebase-js-sdk
| --- | --- |
| [AggregateSpec](./firestore_lite.aggregatespec.md#aggregatespec_interface) | Specifies a set of aggregations and their aliases. |
| [DocumentData](./firestore_lite.documentdata.md#documentdata_interface) | Document data (for use with [setDoc()](./firestore_lite.md#setdoc_ee215ad)<!-- -->) consists of fields mapped to values. |
| [FirestoreDataConverter](./firestore_lite.firestoredataconverter.md#firestoredataconverter_interface) | Converter used by <code>withConverter()</code> to transform user objects of type <code>AppModelType</code> into Firestore data of type <code>DbModelType</code>.<!-- -->Using the converter allows you to specify generic type arguments when storing and retrieving objects from Firestore. |
| [FirestoreDataConverter](./firestore_lite.firestoredataconverter.md#firestoredataconverter_interface) | Converter used by <code>withConverter()</code> to transform user objects of type <code>AppModelType</code> into Firestore data of type <code>DbModelType</code>.<!-- -->Using the converter allows you to specify generic type arguments when storing and retrieving objects from Firestore.<!-- -->In this context, an "AppModel" is a class that is used in an application to package together related information and functionality. Such a class could, for example, have properties with complex, nested data types, properties used for memoization, properties of types not supported by Firestore (such as <code>symbol</code> and <code>bigint</code>), and helper functions that perform compound operations. Such classes are not suitable and/or possible to store into a Firestore database. Instead, instances of such classes need to be converted to "plain old JavaScript objects" (POJOs) with exclusively primitive properties, potentially nested inside other POJOs or arrays of POJOs. In this context, this type is referred to as the "DbModel" and would be an object suitable for persisting into Firestore. For convenience, applications can implement <code>FirestoreDataConverter</code> and register the converter with Firestore objects, such as <code>DocumentReference</code> or <code>Query</code>, to automatically convert <code>AppModel</code> to <code>DbModel</code> when storing into Firestore, and convert <code>DbModel</code> to <code>AppModel</code> when retrieving from Firestore. |
| [Settings](./firestore_lite.settings.md#settings_interface) | Specifies custom configurations for your Cloud Firestore instance. You must set these before invoking any other methods. |
| [TransactionOptions](./firestore_lite.transactionoptions.md#transactionoptions_interface) | Options to customize transaction behavior. |

Expand Down
26 changes: 24 additions & 2 deletions packages/firestore/src/api/snapshot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,22 @@ import { SnapshotListenOptions } from './reference_impl';
* Using the converter allows you to specify generic type arguments when
* storing and retrieving objects from Firestore.
*
* In this context, an "AppModel" is a class that is used in an application to
* package together related information and functionality. Such a class could,
* for example, have properties with complex, nested data types, properties used
* for memoization, properties of types not supported by Firestore (such as
* `symbol` and `bigint`), and helper functions that perform compound
* operations. Such classes are not suitable and/or possible to store into a
* Firestore database. Instead, instances of such classes need to be converted
* to "plain old JavaScript objects" (POJOs) with exclusively primitive
* properties, potentially nested inside other POJOs or arrays of POJOs. In this
* context, this type is referred to as the "DbModel" and would be an object
* suitable for persisting into Firestore. For convenience, applications can
* implement `FirestoreDataConverter` and register the converter with Firestore
* objects, such as `DocumentReference` or `Query`, to automatically convert
* `AppModel` to `DbModel` when storing into Firestore, and convert `DbModel`
* to `AppModel` when retrieving from Firestore.
*
* @example
*
* Simple Example
Expand Down Expand Up @@ -250,8 +266,14 @@ export interface FirestoreDataConverter<
* `snapshot.data(options)`.
*
* Generally, the data returned from `snapshot.data()` can be cast to
* `DbModelType`; however, this is not guaranteed as writes to the database
* may have occurred without a type converter enforcing this specific layout.
* `DbModelType`; however, this is not guaranteed because Firestore does not
* enforce a schema on the database. For example, writes from a previous
* version of the application or writes from another client that did not use a
* type converter could have written data with different properties and/or
* property types. The implementation will need to choose whether to
* gracefully recover from non-conforming data or throw an error.
*
* To override this method, see {@link (FirestoreDataConverter.fromFirestore:1)}.
*
* @param snapshot - A `QueryDocumentSnapshot` containing your data and metadata.
* @param options - The `SnapshotOptions` from the initial call to `data()`.
Expand Down
Loading

0 comments on commit e9869c4

Please sign in to comment.