Reputation: 459
I need to delete an entire collection with multiple documents when a user is deleted, so I decided to create a function so that it fires whenever a user is deleted.
Below is the code.
Cloud Functions (index.js):
exports.onUserDeleted = functions.auth.user().onDelete((user) => {
deleteCollection(admin.firestore(), user.uid, 15);
});
function deleteCollection(db, collectionPath, batchSize) {
var collectionRef = db.collection(collectionPath);
var query = collectionRef.orderBy('__name__').limit(batchSize);
return new Promise((resolve, reject) => {
deleteQueryBatch(db, query, batchSize, resolve, reject);
});
}
function deleteQueryBatch(db, query, batchSize, resolve, reject) {
query.get()
.then((snapshot) => {
// When there are no documents left, we are done
if (snapshot.size === 0) {
return 0;
}
// Delete documents in a batch
var batch = db.batch();
snapshot.docs.forEach((doc) => {
batch.delete(doc.ref);
});
return batch.commit().then(() => {
return snapshot.size;
});
}).then((numDeleted) => {
if (numDeleted === 0) {
resolve();
return;
}
// Recurse on the next process tick, to avoid
// exploding the stack.
process.nextTick(() => {
deleteQueryBatch(db, query, batchSize, resolve, reject);
});
})
.catch(reject);
}
When attempting to perform the firebase deploy command --only functions the following error occurs:
65:11 warning Arrow function expected no return value consistent-return
65:18 warning Avoid nesting promises promise/no-nesting
69:11 error Each then() should return a value or throw promise/always-return
✖ 3 problems (1 error, 2 warnings)
What am I doing wrong?
How can I delete the entire collection when the user is deleted?
If you can post the above code with the logic that I should apply, I will be very grateful.
Upvotes: 4
Views: 2767
Reputation: 83191
Do as follows:
const db = admin.firestore();
exports.onUserDeleted = functions.auth.user().onDelete((user) => {
const collectionRef = db.collection(user.uid);
var promises = [];
return collectionRef.get()
.then(qs => {
qs.forEach(docSnapshot => {
promises.push(docSnapshot.ref.delete());
});
return Promise.all(promises);
})
.catch(error => {
console.log(error);
return false;
});
});
As reflected by your code and as advised in the documentation (see excerpt below) you may delete the docs by batch if the collection is very large. I let you adapt the above code for this, if you consider it is necessary.
If you have larger collections, you may want to delete the documents in smaller batches to avoid out-of-memory errors. Repeat the process until you've deleted the entire collection or subcollection. Source: https://firebase.google.com/docs/firestore/manage-data/delete-data#collections
Upvotes: 9