Tapas Mukherjee
Tapas Mukherjee

Reputation: 2178

Is return value important in Firebase Cloud Functions

I am writing the Firebase Could Functions with TypeScript and the following is a simple method to update a document.

import * as functions from 'firebase-functions';
import * as admin from 'firebase-admin';
admin.initializeApp(functions.config().firebase);

export const handleTestData = functions.firestore.document('test/{docID}').onCreate(async (snap, context) => {
    const data = snap.data();
    if (data) {
        try {
                await admin.firestore().doc('test1/' + context.params.docID + '/').update({duplicate : true});
            } catch (error) {}
    }
});

In this method, the promise is handled by async await and there is no return statement and it's working fine. Most of the examples/tutorials I have seen always have a return statement in each method. Is there any impact/difference I don't return anything in Firebase Cloud Functions? If I should return something, can I return null?

Upvotes: 2

Views: 3433

Answers (1)

Renaud Tarnec
Renaud Tarnec

Reputation: 83058

Is return value important in Firebase Cloud Functions?

Yes, it is really key, in a Cloud Function which performs asynchronous processing (also known as "background functions") to return a JavaScript promise when all the asynchronous processing is complete, as explained in the documentation.

Doing so is important for two main reasons (excerpts from the doc):

  1. You make sure that the Cloud Functions instance running your Cloud Function does not shut down before your function successfully reaches its terminating condition or state.
  2. You can avoid excessive charges from Cloud Functions that run for too long or loop infinitely.

Why is your Cloud Function running correctly even if you don't return a Promise?

Normally your Cloud Function should be terminated before the asynchronous operations are completed, because you don't return a Promise and therefore indicate to the Cloud Functions platform that it can terminate the Cloud Functions instance running the Cloud Function.

But sometimes, the Cloud Functions platform does not terminate the Function immediately and the asynchronous operations can be completed. This is not at all guaranteed and totally out of your control.

Experience has shown that for short asynchronous operations this last case happens quite often and the developer thinks that everything is ok. But, all of sudden, one day, the Cloud Function does not work... and sometimes it does work: The developer is facing an "erratic" behaviour without any clear logic, making things very difficult to debug. You will find a lot of questions in Stack Overflow that illustrate this situation.


So concretely, in your case you can adapt your code like:

export const handleTestData = functions.firestore.document('test/{docID}').onCreate(async (snap, context) => {
    const data = snap.data();
    if (data) {
        try {   
                // See the return below: we return the Promise returned by update()
                return admin.firestore().doc('test1/' + context.params.docID + '/').update({duplicate : true});
         } catch (error) {
               return null;  // <- See the return
        }
    } else {
       return null;  // <- See the return
    }
});

or like

export const handleTestData = functions.firestore.document('test/{docID}').onCreate(async (snap, context) => {
    const data = snap.data();
    if (data) {
        try {
                await admin.firestore().doc('test1/' + context.params.docID + '/').update({duplicate : true});
                return null;  // <- See the return
         } catch (error) {
               return null;  // <- See the return
        }
    } else {
       return null;  // <- See the return
    }
});

Returning null (or true, or 1...) is valid since an async function always returns a Promise.

Upvotes: 4

Related Questions