Skip to content

Commit 20beaef

Browse files
authored
Verify large write batches support (#1501)
Port can write very large batches from Android
1 parent ff294e9 commit 20beaef

File tree

1 file changed

+73
-31
lines changed

1 file changed

+73
-31
lines changed

packages/firestore/test/integration/api/batch_writes.test.ts

Lines changed: 73 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
import * as firestore from '@firebase/firestore-types';
1818
import { expect } from 'chai';
19+
import { AutoId } from '../../../src/util/misc';
1920

2021
import { EventsAccumulator } from '../util/events_accumulator';
2122
import firebase from '../util/firebase_export';
@@ -26,7 +27,7 @@ const Timestamp = firebase.firestore!.Timestamp;
2627
const FieldValue = firebase.firestore!.FieldValue;
2728

2829
apiDescribe('Database batch writes', persistence => {
29-
it('support empty batches', () => {
30+
it('supports empty batches', () => {
3031
return integrationHelpers.withTestDb(persistence, db => {
3132
return db.batch().commit();
3233
});
@@ -88,6 +89,39 @@ apiDescribe('Database batch writes', persistence => {
8889
});
8990
});
9091

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+
91125
it('can delete documents', () => {
92126
return integrationHelpers.withTestDoc(persistence, doc => {
93127
return doc
@@ -317,36 +351,44 @@ apiDescribe('Database batch writes', persistence => {
317351
});
318352
});
319353

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.
331358

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+
);
351393
});
352394
});

0 commit comments

Comments
 (0)