在 Firebase Cloud Functions 上使用带有 PDFMake 的 Promise

Posted

技术标签:

【中文标题】在 Firebase Cloud Functions 上使用带有 PDFMake 的 Promise【英文标题】:Using promises with PDFMake on Firebase Cloud Functions 【发布时间】:2018-04-18 23:37:42 【问题描述】:

我正在使用 PDFMake(PDFKit 的变体)使用实时数据库触发器在 Firebase Cloud Functions 上生成 PDF。该函数从数据库中获取所有相关数据,然后将其传递给应该生成 PDF 的函数。

所有这些都是使用 Promises 完成的。在实际生成 PDF 之前,一切正常。

这是我的主要事件监听器中的代码:

exports.handler = (admin, event, storage) => 
  const quotationData = event.data.val();
  // We must return a Promise when performing async tasks inside Functions
  // Eg: Writing to realtime db
  const companyId = event.params.companyId;
  settings.getCompanyProfile(admin, companyId)
  .then((profile) => 
    return quotPdfHelper.generatePDF(fonts, profile, quotationData, storage);
  )
  .then(() => 
    console.log('Generation Successful. Pass for email');
  )
  .catch((err) => 
    console.log(`Error: $err`);
  );
;

要生成 PDF,这是我的代码:

exports.generatePDF = (fonts, companyInfo, quotationData, storage) => 
  const printer = new PdfPrinter(fonts);
  const docDefinition = 
    content: [
      
        text: [
          
            text: `$companyInfo.title\n`,
            style: 'companyHeader',
          ,
          `$companyInfo.addr_line1, $companyInfo.addr_line2\n`,
          `$companyInfo.city ($companyInfo.state) - INDIA\n`,
          `Email: $companyInfo.email • Web: $companyInfo.website\n`,
          `Phone: $companyInfo.phone\n`,
          `GSTIN: $companyInfo.gst_registration_number  • PAN: AARFK6552G\n`,
        ],
        style: 'body',
         //absolutePosition: x: 20, y: 45
      ,
    ],
    styles: 
      companyHeader: 
        fontSize: 18,
        bold: true,
      ,
      body: 
        fontSize: 10,
      ,
    ,
    pageMargins: 20,
  ;
  return new Promise((resolve, reject) => 
    // const bucket = storage.bucket(`$PROJECT_ID.appspot.com`);
    // const filename = `$Date.now()-quotation.pdf`;
    // const file = bucket.file(filename);
    // const stream = file.createWriteStream( resumable: false );
    const pdfDoc = printer.createPdfKitDocument(docDefinition);
    // pdfDoc.pipe(stream);

    const chunks = [];
    let result = null;

    pdfDoc.on('data', (chunk) => 
      chunks.push(chunk);
    );
    pdfDoc.on('error', (err) => 
      reject(err);
    );
    pdfDoc.on('end', () => 
      result = Buffer.concat(chunks);
      resolve(result);
    );
    pdfDoc.end();
  );
;

这里有什么问题会阻止承诺以及报价代码按预期执行?

在 firebase 日志中,我看到的只有 Function execution took 3288 ms, finished with status: 'ok'

【问题讨论】:

【参考方案1】:

根据执行时间和没有错误,您似乎成功地为 PDF 创建了缓冲区,但实际上并没有从函数中返回它。

.then((profile) => 
  return quotPdfHelper.generatePDF(fonts, profile, quotationData, storage);
)
.then(() => 
  console.log('Generation Successful. Pass for email');
)

在上面的代码中,您将结果传递给下一个 then 块,然后从该块返回 undefined。这个 Promise 链的最终结果将是未定义的。要传递结果,您需要在 Promise 链的末尾返回它:

.then((profile) => 
  return quotPdfHelper.generatePDF(fonts, profile, quotationData, storage);
)
.then(buffer => 
  console.log('Generation Successful. Pass for email');
  return buffer;
)

【讨论】:

【参考方案2】:

我正在尝试使用 firebase 云功能生成 pdf,但我无法定义字体参数。 这是我的定义:

var fonts = 
    Roboto: 
        normal: './fonts/Roboto-Regular.ttf',
        bold: './fonts/Roboto-Bold.ttf',
        italics: './fonts/Roboto-Italic.ttf',
        bolditalics: './fonts/Roboto-BoldItalic.ttf'
    
;

我创建了一个包含上述文件的字体文件夹。但是,无论我在哪里设置字体文件夹(在根目录、函数文件夹或 node_modules 文件夹中),在部署函数时都会收到错误消息“没有这样的文件或目录”。任何建议将不胜感激。

【讨论】:

以上是关于在 Firebase Cloud Functions 上使用带有 PDFMake 的 Promise的主要内容,如果未能解决你的问题,请参考以下文章

在 TypeScript 中为 Firebase Cloud Function 配置 mailgun

在 Firebase Cloud Function 中发出 Youtube Data API 请求

从请求中获取用户信息到 Firebase 中的 Cloud Function

Firebase:Firestore 未在 Cloud Function 的计划函数中更新数据

Firebase Cloud Function在特定时间后自动删除数据[重复]

Firebase Cloud Function 在 .get() 完成之前结束