16
16
17
17
import * as firestore from '@firebase/firestore-types' ;
18
18
import { expect } from 'chai' ;
19
+ import { AutoId } from '../../../src/util/misc' ;
19
20
20
21
import { EventsAccumulator } from '../util/events_accumulator' ;
21
22
import firebase from '../util/firebase_export' ;
@@ -26,7 +27,7 @@ const Timestamp = firebase.firestore!.Timestamp;
26
27
const FieldValue = firebase . firestore ! . FieldValue ;
27
28
28
29
apiDescribe ( 'Database batch writes' , persistence => {
29
- it ( 'support empty batches' , ( ) => {
30
+ it ( 'supports empty batches' , ( ) => {
30
31
return integrationHelpers . withTestDb ( persistence , db => {
31
32
return db . batch ( ) . commit ( ) ;
32
33
} ) ;
@@ -88,6 +89,39 @@ apiDescribe('Database batch writes', persistence => {
88
89
} ) ;
89
90
} ) ;
90
91
92
+ it ( 'can update nested fields' , ( ) => {
93
+ const initialData = {
94
+ desc : 'Description' ,
95
+ owner : { name : 'Jonny' } ,
96
+ 'is.admin' : false
97
+ } ;
98
+ const finalData = {
99
+ desc : 'Description' ,
100
+ owner : { name : 'Sebastian' } ,
101
+ 'is.admin' : true
102
+ } ;
103
+
104
+ return integrationHelpers . withTestDb ( persistence , db => {
105
+ const doc = db . collection ( 'counters' ) . doc ( ) ;
106
+ return doc . firestore
107
+ . batch ( )
108
+ . set ( doc , initialData )
109
+ . update (
110
+ doc ,
111
+ 'owner.name' ,
112
+ 'Sebastian' ,
113
+ new firebase . firestore ! . FieldPath ( 'is.admin' ) ,
114
+ true
115
+ )
116
+ . commit ( )
117
+ . then ( ( ) => doc . get ( ) )
118
+ . then ( docSnapshot => {
119
+ expect ( docSnapshot . exists ) . to . be . ok ;
120
+ expect ( docSnapshot . data ( ) ) . to . deep . equal ( finalData ) ;
121
+ } ) ;
122
+ } ) ;
123
+ } ) ;
124
+
91
125
it ( 'can delete documents' , ( ) => {
92
126
return integrationHelpers . withTestDoc ( persistence , doc => {
93
127
return doc
@@ -317,36 +351,44 @@ apiDescribe('Database batch writes', persistence => {
317
351
} ) ;
318
352
} ) ;
319
353
320
- it ( 'can update nested fields' , ( ) => {
321
- const initialData = {
322
- desc : 'Description' ,
323
- owner : { name : 'Jonny' } ,
324
- 'is.admin' : false
325
- } ;
326
- const finalData = {
327
- desc : 'Description' ,
328
- owner : { name : 'Sebastian' } ,
329
- 'is.admin' : true
330
- } ;
354
+ it ( 'can write very large batches' , ( ) => {
355
+ // On Android, SQLite Cursors are limited reading no more than 2 MB per row
356
+ // (despite being able to write very large values). This test verifies that
357
+ // the local MutationQueue is not subject to this limitation.
331
358
332
- return integrationHelpers . withTestDb ( persistence , db => {
333
- const doc = db . collection ( 'counters' ) . doc ( ) ;
334
- return doc . firestore
335
- . batch ( )
336
- . set ( doc , initialData )
337
- . update (
338
- doc ,
339
- 'owner.name' ,
340
- 'Sebastian' ,
341
- new firebase . firestore ! . FieldPath ( 'is.admin' ) ,
342
- true
343
- )
344
- . commit ( )
345
- . then ( ( ) => doc . get ( ) )
346
- . then ( docSnapshot => {
347
- expect ( docSnapshot . exists ) . to . be . ok ;
348
- expect ( docSnapshot . data ( ) ) . to . deep . equal ( finalData ) ;
349
- } ) ;
350
- } ) ;
359
+ // Create a map containing nearly 1 MB of data. Note that if you use 1024
360
+ // below this will create a document larger than 1 MB, which will be
361
+ // rejected by the backend as too large.
362
+ let kb = 'a' ;
363
+ while ( kb . length < 1000 ) {
364
+ kb += kb ;
365
+ }
366
+ kb = kb . substr ( 0 , 1000 ) ;
367
+ const values = { } ;
368
+ for ( let i = 0 ; i < 1000 ; i ++ ) {
369
+ values [ AutoId . newId ( ) ] = kb ;
370
+ }
371
+
372
+ return integrationHelpers . withTestCollection (
373
+ persistence ,
374
+ { } ,
375
+ async collection => {
376
+ const doc = collection . doc ( 'a' ) ;
377
+ const batch = doc . firestore . batch ( ) ;
378
+
379
+ // Write a batch containing 3 copies of the data, creating a ~3 MB
380
+ // batch. Writing to the same document in a batch is allowed and so long
381
+ // as the net size of the document is under 1 MB the batch is allowed.
382
+ batch . set ( doc , values ) ;
383
+ for ( let i = 0 ; i < 2 ; i ++ ) {
384
+ batch . update ( doc , values ) ;
385
+ }
386
+
387
+ await batch . commit ( ) ;
388
+
389
+ const snap = await doc . get ( ) ;
390
+ expect ( snap . data ( ) ) . to . deep . equal ( values ) ;
391
+ }
392
+ ) ;
351
393
} ) ;
352
394
} ) ;
0 commit comments