Firebase database triggers: onCreate, onUpdate, on

2020-07-17 07:01发布

问题:

On last Firebase functions version, FirebaseDatabase triggers have been updated spliting his functionality with onCreate, onUpdate and onDelete instead of always use onWrite and check if the data have been removed or not in every call.

Can someone give a bit more of information about if it's worth migrate current FirebaseDatabase triggers to new splited functionality and how to update it in an application.

回答1:

Of course is worth it! Split your functionality will make your functions shorted, clear and faster. Also you will avoid infinite calls to DatabaseTriggers to finally apply a return. In the end you will pay for the number of triggers that you app is using, so you should try to avoid useless call to save money!

To implement it in your cloud functions first you will need yo update your firebase-functions version on your package.json inside your function folder and upgrade it to 0.5.9 at least.

About how to use each triggers, lets look closer to an example of onWrite which can be splited.

This function check when a new comment is writed on an specific reference and based on if it have been added, deleted, or updated it plus 1, minus 1 or do nothing :

exports.countComments = functions.database.ref('/workoutPosts/{workoutId}/info/comments/{commentId}').onWrite(event => {
    const workoutId = event.params.workoutId;

    //Comment created
    if (event.data.exists() && !event.data.previous.exists()) {
        return database.ref(`/workoutPosts/${workoutId}/meta/commentsCount`).transaction(addPrivateWorkout => {
            return (addPrivateWorkout || 0) + 1;
        });
        //Comment deleted
    } else if (!event.data.exists() && event.data.previous.exists()) {
        return database.ref(`/workoutPosts/${workoutId}/meta/commentsCount`).transaction(deletePrivateWorkout => {
            return (deletePrivateWorkout || 0) - 1;                
        });
        //Comment updated
    } else if (event.data.exists() && event.data.previous.exists()) {
        return
    }
};

Each update call will be an useless call, and a waste of resources. How can we make this easier? Using the new splitted cloud functions:

exports.countCommentsOnCreate = functions.database.ref('/workoutPosts/{workoutId}/info/comments/{commentId}').onCreate(event => {
    const workoutId = event.params.workoutId;
        return database.ref(`/workoutPosts/${workoutId}/meta/commentsCount`).transaction(addPrivateWorkout => {
            return (addPrivateWorkout || 0) + 1;
        });       
});

exports.countCommentsonDelete = functions.database.ref('/workoutPosts/{workoutId}/info/comments/{commentId}').onDelete(event => {
    const workoutId = event.params.workoutId;

        return database.ref(`/workoutPosts/${workoutId}/meta/commentsCount`).transaction(deletePrivateWorkout => {
            return (deletePrivateWorkout || 0) - 1;
        });
});

You can check more examples and read about this new features on the next post : https://firebase.googleblog.com/2017/07/cloud-functions-realtime-database.html