From f2e1e9b33c85f08280e653f3366d56f494eb96e0 Mon Sep 17 00:00:00 2001 From: Hamish Rickerby Date: Tue, 22 Jan 2019 10:50:46 +1100 Subject: [PATCH] Change clear collections to be a batch function - Firebase only supports 500 changes as part of a batch, so this function needs to loop through larger collections. --- lib/databases/firestore.js | 54 +++++++++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/lib/databases/firestore.js b/lib/databases/firestore.js index e6a3323..68d2192 100644 --- a/lib/databases/firestore.js +++ b/lib/databases/firestore.js @@ -41,18 +41,48 @@ function firestoreQueryParser(collectionRef, queryParams) { }; function emptyCollection(db, collection, callback) { + console.log('Emptying firestore collection', collection); + var batchSize = 300; var collectionRef = db.collection(collection); - var query = collectionRef.get().then(function (querySnapshot) { - var writeBatch = db.batch(); - querySnapshot.forEach(function (documentSnapshot) { - var documentPath = collection + '/' + documentSnapshot.id; - var documentRef = db.doc(documentPath); - writeBatch.delete(documentRef); - }); - writeBatch.commit().then(function () { - if (callback) callback(null); + var query = collectionRef.limit(batchSize); + + console.log('Calling deleteQueryBatch for collection'); + return deleteQueryBatch(db, query, batchSize, callback); +} + +function deleteQueryBatch(db, query, batchSize, callback) { + console.log('In deleteQueryBatch. Get query results'); + query.get() + .then((snapshot) => { + console.log('Snapshot returned'); + console.log('Size', snapshot.size); + if (snapshot.size == 0) { + console.log('Resolving because size is 0'); + return new Promise((resolve) => resolve(0)); + } + + console.log('Setting up batch for deletion'); + var batch = db.batch(); + console.log('Setting up docs for deletion'); + snapshot.docs.forEach((doc) => batch.delete(doc.ref)); + console.log('Starting deletion commit'); + return batch.commit().then(() => { + console.log('Batch committed. Returning size', snapshot.size); + return snapshot.size; + }).then((numDeleted) => { + console.log('Num deleted', numDeleted); + if (numDeleted == 0) { + console.log('Call callback as numDeleted == 0'); + return callback(); + } + + console.log('Schedule next batch for deletion on next tick'); + process.nextTick(() => { + console.log('TICK! Execute next batch'); + deleteQueryBatch(db, query, batchSize, callback); + }); + }).catch((e) => {console.error('Error on get', e); callback(e)}); }); - }); }; function getPrecondition(vm) { @@ -263,14 +293,18 @@ _.extend(Firestore.prototype, { }, clear: function (callback) { + console.log('Entered clear'); this.checkConnection(); var self = this; if (!this.collection) { + console.log('No collection set, just callback'); if (callback) callback(null); return; } + console.log('Calling emptyCollection for', this.collection); + emptyCollection(this.db, this.collection, callback); },