Search code examples
javascriptnode.jsgoogle-cloud-functionsevent-loop

How to make Firebase Cloud Function wait for a stream to close before terminating


I store an object to Cloud Storage like this:

const bucket = getStorage().bucket();
const fileRef = bucket.file("/foo/bar");
const storageWriteStream = fileRef.createWriteStream();

const myFileStream = someLibraryThatCreatesAStream();

storageWriteStream.on("error", (err) => {
  functions.logger.error(err);
 });

storageWriteStream.on("close", (err) => {
  return await getDownloadURL(fileRef)
});

myFileStream.pipe(storageWriteStream);

But when called on the front-end, the result is always null. Since Functions seems to always has trouble with return as part of an event handler, I think it's because Functions doesn't wait for storageWriteStream's close event.

How do I get around this?


Solution

  • You will need to turn the stream's completion into a promise using new Promise, and then either return or await that promise. For example:

    const bucket = getStorage().bucket();
    const fileRef = bucket.file("/foo/bar");
    
    try {
      await new Promise((resolve, reject) => {
        const storageWriteStream = fileRef.createWriteStream();
        const myFileStream = someLibraryThatCreatesAStream();
        storageWriteStream.on("error", reject);
        storageWriteStream.on("close", resolve);
        myFileStream.pipe(storageWriteStream);
      })
      return getDownLoadURL(fileRef);
    } catch (error) {
      functions.logger.error(err);
    }