@@ -36,7 +36,13 @@ import { AbstractUserDataWriter } from '../lite-api/user_data_writer';
36
36
import { Document } from '../model/document' ;
37
37
import { DocumentKey } from '../model/document_key' ;
38
38
import { debugAssert , fail } from '../util/assert' ;
39
+ import {
40
+ BundleBuilder ,
41
+ DocumentSnapshotBundleData ,
42
+ QuerySnapshotBundleData
43
+ } from '../util/bundle_builder_impl' ;
39
44
import { Code , FirestoreError } from '../util/error' ;
45
+ import { AutoId } from '../util/misc' ;
40
46
41
47
import { Firestore } from './database' ;
42
48
import { SnapshotListenOptions } from './reference_impl' ;
@@ -496,6 +502,46 @@ export class DocumentSnapshot<
496
502
}
497
503
return undefined ;
498
504
}
505
+
506
+ toJSON ( ) : object {
507
+ const document = this . _document ;
508
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
509
+ const result : any = { } ;
510
+ result [ 'bundle' ] = '' ;
511
+ result [ 'source' ] = 'DocumentSnapshot' ;
512
+
513
+ if (
514
+ ! document ||
515
+ ! document . isValidDocument ( ) ||
516
+ ! document . isFoundDocument ( )
517
+ ) {
518
+ return result ;
519
+ }
520
+ const builder : BundleBuilder = new BundleBuilder (
521
+ this . _firestore ,
522
+ AutoId . newId ( )
523
+ ) ;
524
+ const documentData = this . _userDataWriter . convertObjectMap (
525
+ document . data . value . mapValue . fields ,
526
+ 'previous'
527
+ ) ;
528
+ if ( this . metadata . hasPendingWrites ) {
529
+ throw new FirestoreError (
530
+ Code . FAILED_PRECONDITION ,
531
+ 'DocumentSnapshot.toJSON() attempted to serialize a document with pending writes. ' +
532
+ 'Await waitForPendingWrites() before invoking toJSON().'
533
+ ) ;
534
+ }
535
+ builder . addBundleDocument (
536
+ documentToDocumentSnapshotBundleData (
537
+ this . ref . path ,
538
+ documentData ,
539
+ document
540
+ )
541
+ ) ;
542
+ result [ 'bundle' ] = builder . build ( ) ;
543
+ return result ;
544
+ }
499
545
}
500
546
501
547
/**
@@ -651,6 +697,52 @@ export class QuerySnapshot<
651
697
652
698
return this . _cachedChanges ;
653
699
}
700
+
701
+ toJSON ( ) : object {
702
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
703
+ const result : any = { } ;
704
+ result [ 'source' ] = 'QuerySnapshot' ;
705
+ const builder : BundleBuilder = new BundleBuilder (
706
+ this . _firestore ,
707
+ AutoId . newId ( )
708
+ ) ;
709
+ const databaseId = this . _firestore . _databaseId . database ;
710
+ const projectId = this . _firestore . _databaseId . projectId ;
711
+ const parent = `projects/${ projectId } /databases/${ databaseId } /documents` ;
712
+ const docBundleDataArray : DocumentSnapshotBundleData [ ] = [ ] ;
713
+ const docArray = this . docs ;
714
+ docArray . forEach ( doc => {
715
+ if ( doc . _document === null ) {
716
+ return ;
717
+ }
718
+ const documentData = this . _userDataWriter . convertObjectMap (
719
+ doc . _document . data . value . mapValue . fields ,
720
+ 'previous'
721
+ ) ;
722
+ if ( this . metadata . hasPendingWrites ) {
723
+ throw new FirestoreError (
724
+ Code . FAILED_PRECONDITION ,
725
+ 'QuerySnapshot.toJSON() attempted to serialize a document with pending writes. ' +
726
+ 'Await waitForPendingWrites() before invoking toJSON().'
727
+ ) ;
728
+ }
729
+ docBundleDataArray . push (
730
+ documentToDocumentSnapshotBundleData (
731
+ doc . ref . path ,
732
+ documentData ,
733
+ doc . _document
734
+ )
735
+ ) ;
736
+ } ) ;
737
+ const bundleData : QuerySnapshotBundleData = {
738
+ query : this . query . _query ,
739
+ parent,
740
+ docBundleDataArray
741
+ } ;
742
+ builder . addBundleQuery ( bundleData ) ;
743
+ result [ 'bundle' ] = builder . build ( ) ;
744
+ return result ;
745
+ }
654
746
}
655
747
656
748
/** Calculates the array of `DocumentChange`s for a given `ViewSnapshot`. */
@@ -790,3 +882,20 @@ export function snapshotEqual<AppModelType, DbModelType extends DocumentData>(
790
882
791
883
return false ;
792
884
}
885
+
886
+ // Formats Document data for bundling a DocumentSnapshot.
887
+ function documentToDocumentSnapshotBundleData (
888
+ path : string ,
889
+ documentData : DocumentData ,
890
+ document : Document
891
+ ) : DocumentSnapshotBundleData {
892
+ return {
893
+ documentData,
894
+ documentKey : document . mutableCopy ( ) . key ,
895
+ documentPath : path ,
896
+ documentExists : true ,
897
+ createdTime : document . createTime . toTimestamp ( ) ,
898
+ readTime : document . readTime . toTimestamp ( ) ,
899
+ versionTime : document . version . toTimestamp ( )
900
+ } ;
901
+ }
0 commit comments