jean d'arme
jean d'arme

Reputation: 4343

How to continue running Firebase Cloud Function after request is finished

Really bizarre that Firebase doesn't seem to work quite like typical Express app. Whatever I write in Express and copy-paste to Firebase Functions I typically get error. There is one that I can't figure out on my own though.

This endpoint is designed to start a function and live long enough to finish even longer task. That request is a webhook (send docs, we will transform them and ping you when it's done to specified another webhook). Very simplified example below:

router.post('/', (req, res) => {
  try {
    generateZipWithDocuments(data) // on purpose it's not async so request can return freely
    res.sendStatus(201)
  
  } catch (error) {
    res.send({ error })
  }
})

On my local machine it works (both pure Express app and locally emulated Firebase Functions), but in the cloud it has problems and even though I put a cavalcade of console.log() I don't get much information. No error from Firebase.

Upvotes: 1

Views: 1754

Answers (1)

Renaud Tarnec
Renaud Tarnec

Reputation: 83048

If generateZipWithDocuments() is not asynchronous res.sendStatus() will be immediately executed after it, and the Cloud Function will be terminated (and the job done by generateZipWithDocuments() will not be completed). See the doc here for more details.

You have two possibilities:

  1. You make it asynchronous and you wait until its job is completed before sending the response. You would typically use async/await for that. Note that the maximum execution time for a Cloud Function is 9 minutes.
  2. You delegate the long time execution job to another Cloud Function and, then, you send the response. For delegating the job to another Cloud Function, you should use Pub/Sub. See Pub/Sub triggers, the sample quickstart, and this SO thread for more details on how to implement that. In the Pub/Sub triggered Function, when the job is done you can inform the user via an email, a notification, the update of a Firestore document on which you have set a listener, etc... If generateZipWithDocuments() takes a long time, it is clearly the most user friendly option.

Upvotes: 4

Related Questions