0

I'm using a firebase trigger that when a certain document is deleted, I can get the path to a collection of documents that I wish to be deleted using a firebase cloud function. So far after much headache my onDelete function works.

on the trigger I get the id I need to get the path to the collection I want deleted, then I use .get() to retrieve the documents from the collection
then I use a forEach to get all the documents i want to be deleted.

my issues is I want to use a batch delete as I've read this is the best way to do it because if you have more than 500 documents to delete you could come up with errors unless you use a batch delete

so when I loop through the documents I use batch.delete(document.id), then just outside of the loop I call batch.commit()

when the function is triggered I get this message in the terminal

⚠  Your function was killed because it raised an unhandled error.
i  functions: Beginning execution of "onDeleteTriggers"
>  the doc that We need to delete is  KLvuLSa1uSsVjaKmVOB5
>  ahOh there was an error deleting the documents
i  functions: Finished "onDeleteTriggers" in ~1s

my full code is below

const functions = require("firebase-functions");
const admin = require("firebase-admin");
const { firestore } = require("firebase-admin");
admin.initializeApp();

 exports.onDeleteTriggers = functions.firestore.document('recentMsg/currentuid/touid/{documentId}').onDelete(async(snap, context) => {
     const params = context.params     
     const db = admin.firestore();
     const batch = db.batch()

     await admin.firestore().collection(`messages/currentuid/${params.documentId}`)
     .get()
     .then(snap => {  
       snap.forEach(document => {
         console.log(`the doc that We need to delete is  ${document.id}`)
        
        //this takes in the documents i want to delete 
          batch.delete(document.id);
       })
      // then commit them 
       batch.commit();
     })
     .catch(functionCalledToHandleError)
    
})


function functionCalledToHandleError() {
  console.log('ahOh there was an error deleting the documents')
}



I'm extremely news to firebase cloud functions, so I'm just going on what I've read which Im finding quite difficult as I'm new. any help will be appreciated

1 Answers1

1

Try to use this function for deleting a collection:

async function deleteCollection(db, collectionPath, batchSize = 100) {
  const collectionRef = db.collection(collectionPath);
  const query = collectionRef.orderBy("__name__").limit(batchSize);

  return new Promise((resolve, reject) => {
    deleteQueryBatch(db, query, resolve).catch(reject);
  });
}

async function deleteQueryBatch(db, query, resolve) {
  const snapshot = await query.get();

  const batchSize = snapshot.size;
  if (batchSize === 0) {
    // When there are no documents left, we are done
    resolve();
    return;
  }

  // Delete documents in a batch
  const batch = db.batch();
  snapshot.docs.forEach((doc) => {
    batch.delete(doc.ref);
  });
  await batch.commit();

  // Recurse on the next process tick, to avoid
  // exploding the stack.
  process.nextTick(() => {
    deleteQueryBatch(db, query, resolve);
  });
}

export { deleteCollection, deleteQueryBatch };

I would recommend to store it into a file so you can reuse it if needed in another function.

Tarik Huber
  • 7,061
  • 2
  • 12
  • 18
  • Great to hear that. It would be great if you mark the answer as helpful or answered :) – Tarik Huber Jun 11 '21 at 20:16
  • Tarik Huber, is it necessary to order the collection by "__name__" if we are deleting the documents anyway? – Jo Momma Oct 07 '21 at 13:51
  • 1
    A `limit` requires an `orderBy`. That is the reason we have on there. And the `__name__` represents the document ID so it's actually just the order they where added to the collection. – Tarik Huber Oct 11 '21 at 06:50