'How to stop firebase functions from propagating triggers

I have a Firebase function to decrease the commentCount when a comment is deleted, like this

export const onArticleCommentDeleted = functions.firestore.document('articles/{articleId}/comments/{uid}').onDelete((snapshot, context) => {
    return db.collection('articles').doc(context.params.articleId).update({
        commentCount: admin.firestore.FieldValue.increment(-1)
    })
})

I also have firebase functions to recursively delete comments of an article when it's deleted

export const onArticleDeleted = functions.firestore.document('articles/{id}').onDelete((snapshot, context) => {
    const commentsRef = db.collection('articles').doc(snapshot.id).collection('comments');
    db.recursiveDelete(commentsRef); // this triggers the onArticleCommentDeleted multiple times
})

When I delete an article, the onArticleCommentDeleted is triggered and it tries to update the article that has already been deleted. Of course I can check if the article exists before updating it. But it's really cumbersome and waste of resources.

Are there any ways to avoid from propagating further triggers?



Solution 1:[1]

I think the problem arises from the way I make use of the trigger. In general, it's not a good idea to implement an onDelete trigger on a child document updates its own parent. This will surely cause conflict.

Instead, at the client side, I use transaction

...
runTransaction(async trans => {
    trans.delete(commentRef);
    trans.update(articleRef, {
        commentCount: admin.firestore.FieldValue.increment(-1)
    })
})

This makes sure that if one of the operation fails they both fail, and eradicates the triggers. Relying to the client side is not the best idea, but I think we can consider the trade off.

Solution 2:[2]

There is no way to prevent triggering the Cloud Function on the comments when you delete the comments for that article. You will have to check for that condition in the function code itself, as you already said.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Anh Nguyen
Solution 2 Frank van Puffelen