Skip to content

Commit c88ea8e

Browse files
authored
[FEAT] Doc/QuerySnapshot fromJSON (#8960)
Add a methods to parse bundles synchronously to extract single `DocumentSnapshots` or `QuerySnapshots` containing documents. Hook the new bundle parser up the `documentSnapshotFromJSON` and `querySnapshotFromJSON`. ### Testing Local testing with Next.js app. Added unit tests and integration tests. ### API Changes go/fs-js-json-serialization
1 parent c211ea2 commit c88ea8e

25 files changed

+1352
-322
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,8 @@ export function documentId(): FieldPath;
137137
export class DocumentReference<AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData> {
138138
readonly converter: FirestoreDataConverter<AppModelType, DbModelType> | null;
139139
readonly firestore: Firestore;
140-
static fromJSON<NewAppModelType = DocumentData, NewDbModelType extends DocumentData = DocumentData>(firestore: Firestore, json: object, converter?: FirestoreDataConverter<NewAppModelType, NewDbModelType>): DocumentReference<NewAppModelType, NewDbModelType>;
140+
static fromJSON(firestore: Firestore, json: object): DocumentReference;
141+
static fromJSON<NewAppModelType = DocumentData, NewDbModelType extends DocumentData = DocumentData>(firestore: Firestore, json: object, converter: FirestoreDataConverter<NewAppModelType, NewDbModelType>): DocumentReference<NewAppModelType, NewDbModelType>;
141142
get id(): string;
142143
get parent(): CollectionReference<AppModelType, DbModelType>;
143144
get path(): string;

common/api-review/firestore.api.md

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ export function documentId(): FieldPath;
163163
export class DocumentReference<AppModelType = DocumentData, DbModelType extends DocumentData = DocumentData> {
164164
readonly converter: FirestoreDataConverter<AppModelType, DbModelType> | null;
165165
readonly firestore: Firestore;
166-
static fromJSON<NewAppModelType = DocumentData, NewDbModelType extends DocumentData = DocumentData>(firestore: Firestore, json: object, converter?: FirestoreDataConverter<NewAppModelType, NewDbModelType>): DocumentReference<NewAppModelType, NewDbModelType>;
166+
static fromJSON(firestore: Firestore, json: object): DocumentReference;
167+
static fromJSON<NewAppModelType = DocumentData, NewDbModelType extends DocumentData = DocumentData>(firestore: Firestore, json: object, converter: FirestoreDataConverter<NewAppModelType, NewDbModelType>): DocumentReference<NewAppModelType, NewDbModelType>;
167168
get id(): string;
168169
get parent(): CollectionReference<AppModelType, DbModelType>;
169170
get path(): string;
@@ -182,10 +183,15 @@ export class DocumentSnapshot<AppModelType = DocumentData, DbModelType extends D
182183
get id(): string;
183184
readonly metadata: SnapshotMetadata;
184185
get ref(): DocumentReference<AppModelType, DbModelType>;
185-
// (undocumented)
186186
toJSON(): object;
187187
}
188188

189+
// @public
190+
export function documentSnapshotFromJSON(db: Firestore, json: object): DocumentSnapshot;
191+
192+
// @public
193+
export function documentSnapshotFromJSON<AppModelType, DbModelType extends DocumentData = DocumentData>(db: Firestore, json: object, converter: FirestoreDataConverter<AppModelType, DbModelType>): DocumentSnapshot<AppModelType, DbModelType>;
194+
189195
export { EmulatorMockTokenOptions }
190196

191197
// @public @deprecated
@@ -468,40 +474,40 @@ export function onSnapshot<AppModelType, DbModelType extends DocumentData>(query
468474
export function onSnapshot<AppModelType, DbModelType extends DocumentData>(query: Query<AppModelType, DbModelType>, options: SnapshotListenOptions, onNext: (snapshot: QuerySnapshot<AppModelType, DbModelType>) => void, onError?: (error: FirestoreError) => void, onCompletion?: () => void): Unsubscribe;
469475

470476
// @public
471-
export function onSnapshot<AppModelType, DbModelType extends DocumentData>(firestore: Firestore, snapshotJson: object, onNext: (snapshot: QuerySnapshot<AppModelType, DbModelType>) => void, onError?: (error: FirestoreError) => void, onCompletion?: () => void, converter?: FirestoreDataConverter<DbModelType>): Unsubscribe;
477+
export function onSnapshotResume<AppModelType, DbModelType extends DocumentData>(firestore: Firestore, snapshotJson: object, onNext: (snapshot: QuerySnapshot<AppModelType, DbModelType>) => void, onError?: (error: FirestoreError) => void, onCompletion?: () => void, converter?: FirestoreDataConverter<DbModelType>): Unsubscribe;
472478

473479
// @public
474-
export function onSnapshot<AppModelType, DbModelType extends DocumentData>(firestore: Firestore, snapshotJson: object, onNext: (snapshot: DocumentSnapshot<AppModelType, DbModelType>) => void, onError?: (error: FirestoreError) => void, onCompletion?: () => void, converter?: FirestoreDataConverter<DbModelType>): Unsubscribe;
480+
export function onSnapshotResume<AppModelType, DbModelType extends DocumentData>(firestore: Firestore, snapshotJson: object, onNext: (snapshot: DocumentSnapshot<AppModelType, DbModelType>) => void, onError?: (error: FirestoreError) => void, onCompletion?: () => void, converter?: FirestoreDataConverter<DbModelType>): Unsubscribe;
475481

476482
// @public
477-
export function onSnapshot<AppModelType, DbModelType extends DocumentData>(firestore: Firestore, snapshotJson: object, options: SnapshotListenOptions, onNext: (snapshot: QuerySnapshot<AppModelType, DbModelType>) => void, onError?: (error: FirestoreError) => void, onCompletion?: () => void, converter?: FirestoreDataConverter<DbModelType>): Unsubscribe;
483+
export function onSnapshotResume<AppModelType, DbModelType extends DocumentData>(firestore: Firestore, snapshotJson: object, options: SnapshotListenOptions, onNext: (snapshot: QuerySnapshot<AppModelType, DbModelType>) => void, onError?: (error: FirestoreError) => void, onCompletion?: () => void, converter?: FirestoreDataConverter<DbModelType>): Unsubscribe;
478484

479485
// @public
480-
export function onSnapshot<AppModelType, DbModelType extends DocumentData>(firestore: Firestore, snapshotJson: object, options: SnapshotListenOptions, onNext: (snapshot: DocumentSnapshot<AppModelType, DbModelType>) => void, onError?: (error: FirestoreError) => void, onCompletion?: () => void, converter?: FirestoreDataConverter<DbModelType>): Unsubscribe;
486+
export function onSnapshotResume<AppModelType, DbModelType extends DocumentData>(firestore: Firestore, snapshotJson: object, options: SnapshotListenOptions, onNext: (snapshot: DocumentSnapshot<AppModelType, DbModelType>) => void, onError?: (error: FirestoreError) => void, onCompletion?: () => void, converter?: FirestoreDataConverter<DbModelType>): Unsubscribe;
481487

482488
// @public
483-
export function onSnapshot<AppModelType, DbModelType extends DocumentData>(firestore: Firestore, snapshotJson: object, observer: {
489+
export function onSnapshotResume<AppModelType, DbModelType extends DocumentData>(firestore: Firestore, snapshotJson: object, observer: {
484490
next: (snapshot: QuerySnapshot<AppModelType, DbModelType>) => void;
485491
error?: (error: FirestoreError) => void;
486492
complete?: () => void;
487493
}, converter?: FirestoreDataConverter<DbModelType>): Unsubscribe;
488494

489495
// @public
490-
export function onSnapshot<AppModelType, DbModelType extends DocumentData>(firestore: Firestore, snapshotJson: object, observer: {
496+
export function onSnapshotResume<AppModelType, DbModelType extends DocumentData>(firestore: Firestore, snapshotJson: object, observer: {
491497
next: (snapshot: DocumentSnapshot<AppModelType, DbModelType>) => void;
492498
error?: (error: FirestoreError) => void;
493499
complete?: () => void;
494500
}, converter?: FirestoreDataConverter<DbModelType>): Unsubscribe;
495501

496502
// @public
497-
export function onSnapshot<AppModelType, DbModelType extends DocumentData>(firestore: Firestore, snapshotJson: object, options: SnapshotListenOptions, observer: {
503+
export function onSnapshotResume<AppModelType, DbModelType extends DocumentData>(firestore: Firestore, snapshotJson: object, options: SnapshotListenOptions, observer: {
498504
next: (snapshot: QuerySnapshot<AppModelType, DbModelType>) => void;
499505
error?: (error: FirestoreError) => void;
500506
complete?: () => void;
501507
}, converter?: FirestoreDataConverter<DbModelType>): Unsubscribe;
502508

503509
// @public
504-
export function onSnapshot<AppModelType, DbModelType extends DocumentData>(firestore: Firestore, snapshotJson: object, options: SnapshotListenOptions, observer: {
510+
export function onSnapshotResume<AppModelType, DbModelType extends DocumentData>(firestore: Firestore, snapshotJson: object, options: SnapshotListenOptions, observer: {
505511
next: (snapshot: DocumentSnapshot<AppModelType, DbModelType>) => void;
506512
error?: (error: FirestoreError) => void;
507513
complete?: () => void;
@@ -658,10 +664,15 @@ export class QuerySnapshot<AppModelType = DocumentData, DbModelType extends Docu
658664
readonly metadata: SnapshotMetadata;
659665
readonly query: Query<AppModelType, DbModelType>;
660666
get size(): number;
661-
// (undocumented)
662667
toJSON(): object;
663668
}
664669

670+
// @public
671+
export function querySnapshotFromJSON(db: Firestore, json: object): QuerySnapshot;
672+
673+
// @public
674+
export function querySnapshotFromJSON<AppModelType, DbModelType extends DocumentData = DocumentData>(db: Firestore, json: object, converter: FirestoreDataConverter<AppModelType, DbModelType>): QuerySnapshot<AppModelType, DbModelType>;
675+
665676
// @public
666677
export class QueryStartAtConstraint extends QueryConstraint {
667678
readonly type: 'startAt' | 'startAfter';

docs-devsite/firestore_.documentreference.md

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export declare class DocumentReference<AppModelType = DocumentData, DbModelType
3333

3434
| Method | Modifiers | Description |
3535
| --- | --- | --- |
36+
| [fromJSON(firestore, json)](./firestore_.documentreference.md#documentreferencefromjson) | <code>static</code> | Builds a <code>DocumentReference</code> instance from a JSON object created by [DocumentReference.toJSON()](./firestore_.documentreference.md#documentreferencetojson)<!-- -->. |
3637
| [fromJSON(firestore, json, converter)](./firestore_.documentreference.md#documentreferencefromjson) | <code>static</code> | Builds a <code>DocumentReference</code> instance from a JSON object created by [DocumentReference.toJSON()](./firestore_.documentreference.md#documentreferencetojson)<!-- -->. |
3738
| [toJSON()](./firestore_.documentreference.md#documentreferencetojson) | | Returns a JSON-serializable representation of this <code>DocumentReference</code> instance. |
3839
| [withConverter(converter)](./firestore_.documentreference.md#documentreferencewithconverter) | | Applies a custom data converter to this <code>DocumentReference</code>, allowing you to use your own custom model objects with Firestore. When you call [setDoc()](./firestore_lite.md#setdoc_ee215ad)<!-- -->, [getDoc()](./firestore_lite.md#getdoc_4569087)<!-- -->, etc. with the returned <code>DocumentReference</code> instance, the provided converter will convert between Firestore data of type <code>NewDbModelType</code> and your custom type <code>NewAppModelType</code>. |
@@ -105,16 +106,39 @@ Builds a `DocumentReference` instance from a JSON object created by [DocumentRef
105106
<b>Signature:</b>
106107

107108
```typescript
108-
static fromJSON<NewAppModelType = DocumentData, NewDbModelType extends DocumentData = DocumentData>(firestore: Firestore, json: object, converter?: FirestoreDataConverter<NewAppModelType, NewDbModelType>): DocumentReference<NewAppModelType, NewDbModelType>;
109+
static fromJSON(firestore: Firestore, json: object): DocumentReference;
109110
```
110111

111112
#### Parameters
112113

113114
| Parameter | Type | Description |
114115
| --- | --- | --- |
115-
| firestore | [Firestore](./firestore_.firestore.md#firestore_class) | |
116+
| firestore | [Firestore](./firestore_.firestore.md#firestore_class) | The [Firestore](./firestore_.firestore.md#firestore_class) instance the snapshot should be loaded for. |
116117
| json | object | a JSON object represention of a <code>DocumentReference</code> instance |
117-
| converter | [FirestoreDataConverter](./firestore_.firestoredataconverter.md#firestoredataconverter_interface)<!-- -->&lt;NewAppModelType, NewDbModelType&gt; | |
118+
119+
<b>Returns:</b>
120+
121+
[DocumentReference](./firestore_.documentreference.md#documentreference_class)
122+
123+
an instance of [DocumentReference](./firestore_.documentreference.md#documentreference_class) if the JSON object could be parsed. Throws a [FirestoreError](./firestore_.firestoreerror.md#firestoreerror_class) if an error occurs.
124+
125+
## DocumentReference.fromJSON()
126+
127+
Builds a `DocumentReference` instance from a JSON object created by [DocumentReference.toJSON()](./firestore_.documentreference.md#documentreferencetojson)<!-- -->.
128+
129+
<b>Signature:</b>
130+
131+
```typescript
132+
static fromJSON<NewAppModelType = DocumentData, NewDbModelType extends DocumentData = DocumentData>(firestore: Firestore, json: object, converter: FirestoreDataConverter<NewAppModelType, NewDbModelType>): DocumentReference<NewAppModelType, NewDbModelType>;
133+
```
134+
135+
#### Parameters
136+
137+
| Parameter | Type | Description |
138+
| --- | --- | --- |
139+
| firestore | [Firestore](./firestore_.firestore.md#firestore_class) | The [Firestore](./firestore_.firestore.md#firestore_class) instance the snapshot should be loaded for. |
140+
| json | object | a JSON object represention of a <code>DocumentReference</code> instance |
141+
| converter | [FirestoreDataConverter](./firestore_.firestoredataconverter.md#firestoredataconverter_interface)<!-- -->&lt;NewAppModelType, NewDbModelType&gt; | Converts objects to and from Firestore. |
118142

119143
<b>Returns:</b>
120144

docs-devsite/firestore_.documentsnapshot.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export declare class DocumentSnapshot<AppModelType = DocumentData, DbModelType e
4141
| [data(options)](./firestore_.documentsnapshot.md#documentsnapshotdata) | | Retrieves all fields in the document as an <code>Object</code>. Returns <code>undefined</code> if the document doesn't exist.<!-- -->By default, <code>serverTimestamp()</code> values that have not yet been set to their final value will be returned as <code>null</code>. You can override this by passing an options object. |
4242
| [exists()](./firestore_.documentsnapshot.md#documentsnapshotexists) | | Returns whether or not the data exists. True if the document exists. |
4343
| [get(fieldPath, options)](./firestore_.documentsnapshot.md#documentsnapshotget) | | Retrieves the field specified by <code>fieldPath</code>. Returns <code>undefined</code> if the document or field doesn't exist.<!-- -->By default, a <code>serverTimestamp()</code> that has not yet been set to its final value will be returned as <code>null</code>. You can override this by passing an options object. |
44-
| [toJSON()](./firestore_.documentsnapshot.md#documentsnapshottojson) | | |
44+
| [toJSON()](./firestore_.documentsnapshot.md#documentsnapshottojson) | | Returns a JSON-serializable representation of this <code>DocumentSnapshot</code> instance. |
4545

4646
## DocumentSnapshot.(constructor)
4747

@@ -147,6 +147,8 @@ The data at the specified field location or undefined if no such field exists in
147147

148148
## DocumentSnapshot.toJSON()
149149

150+
Returns a JSON-serializable representation of this `DocumentSnapshot` instance.
151+
150152
<b>Signature:</b>
151153

152154
```typescript
@@ -156,3 +158,5 @@ toJSON(): object;
156158

157159
object
158160

161+
a JSON representation of this object.
162+

0 commit comments

Comments
 (0)