Home > database >  Terminate asynchronous firebase-function properly
Terminate asynchronous firebase-function properly

Time:01-20

As described in the firebase docs, it is required to

"resolve functions that perform asynchronous processing (also known as "background functions") by returning a JavaScript promise." (screenshot of logger showing bad function termination

What should I do to terminate the function properly?

// adapting the demo code by Volodymyr Golosay published on https://medium.com/firebase-developers/how-to-generate-and-store-a-pdf-with-firebase-7faebb74ccbf
// library installed -> npm install pdfmake
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
const db = admin.firestore();

const Printer = require('pdfmake');
const fonts = require('pdfmake/build/vfs_fonts.js');
const fontDescriptors = {
  Roboto: {
    normal: Buffer.from(fonts.pdfMake.vfs['Roboto-Regular.ttf'], 'base64'),
    bold: Buffer.from(fonts.pdfMake.vfs['Roboto-Medium.ttf'], 'base64'),
    italics: Buffer.from(fonts.pdfMake.vfs['Roboto-Italic.ttf'], 'base64'),
    bolditalics: Buffer.from(fonts.pdfMake.vfs['Roboto-Italic.ttf'], 'base64'),
  }
};


exports.generateDemoPdf = functions
// trigger by 'document.onCreate', while demo uses 'https.onRequest'
.firestore   
  .document('collection/{docId}')
  .onCreate(async (snap, context) => {     

    const printer = new Printer(fontDescriptors);
    const chunks = [];
    // define the content of the pdf-file
    const docDefinition = {
        content: [{
            text: 'PDF text is here.',
            fontSize: 19 }
        ]
    };

  
  const pdfDoc = printer.createPdfKitDocument(docDefinition);

  pdfDoc.on('data', (chunk) => {
    chunks.push(chunk);
  });

  pdfDoc.on('end', async () => {
    const result = Buffer.concat(chunks);
    
    // Upload generated file to the Cloud Storage
    const docId = "123456789"
    const bucket = admin.storage().bucket();
    const fileRef = bucket.file(`${docId}.pdf`, { 
        metadata: { 
            contentType: 'application/pdf'
        } 
    });
    await fileRef.save(result);    
    console.log('result is saved'); 
    // NEEDS PROPER TERMINATION HERE?? NEEDS TO RETURN A PROMISE?? FIREBASE DOCS: https://firebase.google.com/docs/functions/terminate-functions?hl=en
    // the demo with 'https.onRequest' uses the following line to terminate the function properly:
    // response.send(result);     
  });  

  pdfDoc.on('error', (err) => {    
    return functions.logger.log('An error occured!');
  });

  pdfDoc.end();
});

CodePudding user response:

I think everything is fine in your code. It seems it takes 1m 34s to render the file and save it to storage.

Cloud function will be terminated automatically when all micro and macro tasks are done. Right after you last await.

To check how long does it takes and does it terminate right after saving, you can run the firebase emulator on your local machine.

You will see logs in the terminal and simultaneously watch on storage.

CodePudding user response:

I suspect you did terminate properly - that's the nature of promises. Your function "terminated" with a 200 status, returning a PROMISE for the results of the PDF save. When the PDF save actually terminates later, the result is logged and the promise resolved. This behavior is WHY you return the promise.

  •  Tags:  
  • Related