微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 pdfmake 生成 pdf 并使用 Firebase 云功能将其存储在 Firebase 存储中

如何解决如何使用 pdfmake 生成 pdf 并使用 Firebase 云功能将其存储在 Firebase 存储中

我正在 Firebase 中开发一个应用程序。创建订单后,我想生成其发票。我已经实现了该功能,但是由于创建了 pdf,所以 URL 有问题,但是正如您在图片中看到的,打开它的 URL 是错误的。

这是我在 Cloud Function index.js 中的代码

'use strict';

const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
const nodemailer = require('nodemailer');
//...

var PdfPrinter = require('pdfmake');
const fs = require('fs');

var fonts = {
  Courier: {
    normal: 'Courier',bold: 'Courier-Bold',italics: 'Courier-Oblique',bolditalics: 'Courier-Boldoblique'
  },Helvetica: {
    normal: 'Helvetica',bold: 'Helvetica-Bold',italics: 'Helvetica-Oblique',bolditalics: 'Helvetica-Boldoblique'
  },Times: {
    normal: 'Times-Roman',bold: 'Times-Bold',italics: 'Times-Italic',bolditalics: 'Times-BoldItalic'
  },Symbol: {
    normal: 'Symbol'
  },ZapfDingbats: {
    normal: 'ZapfDingbats'
  }
};

exports.generateInvoice = functions.database.ref('/pedidos/{documentId}').onCreate((snap,context) => {
  return (async () => {
    var docDeFinition = {
      pageSize: 'A4',pageOrientation: 'portrait',content: [
        //Cabecera
        { image: 'img/logo.png',width: 90,alignment: 'left' },{ text: `Pedido${snap.key}`,fontSize: 32,margin: [0,8,0] }
      
        //Body
      ],defaultStyle: {
        font: 'Helvetica'
      }
    };
    console.log("Doc defined okey");

    const pdfName = snap.key + ".pdf";
    const fileName = "pedidos/" + pdfName;
    const myPDFfile = admin.storage().bucket().file(fileName);

    var printer = new PdfPrinter(fonts);
    var pdfDoc = printer.createPdfKitDocument(docDeFinition);
    pdfDoc.pipe(myPDFfile.createWriteStream());
    pdfDoc.end();

  })().then(() => {

  }).catch (err => {
    console.log("An error has ocurred " + err);
  });
});

如您所见,pdf 已正确创建,但 URL 错误,我无法打开它。

enter image description here

如果有人帮助我,我将不胜感激。

解决方法

这是通过 Admin SDK 将文件上传到 Cloud Storage 时的一个已知问题,请参阅 https://github.com/firebase/firebase-admin-node/issues/694

正如您将读到的,主要有两种可能的方法:

  • 使用 getSignedUrl() 方法获取签名 URL(允许有限时间访问文件)并将其保存在某处,例如在实时数据库或 Firestore 中。由于它的生命周期有限,您可能需要根据您的功能要求定期更新它,例如通过预定的 Cloud Functions 功能。
  • 向文件元数据添加 firebaseStorageDownloadTokens 值。虽然它似乎有效(请参阅下面的代码),但似乎也不推荐使用,因为它不是 Google Cloud Storage 的官方功能,请参阅 here

如果你想使用第二个选项(尽管它似乎不被推荐),下面的方法可以解决问题:

const pdfDoc = printer.createPdfKitDocument(docDefinition);
pdfDoc.pipe(myPDFfile.createWriteStream());

pdfDoc.on('end',async function () {
   const uniqueId = admin.firestore().collection("_").doc().id;
   await myPDFfile.setMetadata({
        metadata: {
           firebaseStorageDownloadTokens: uniqueId,}
   });
});

pdfDoc.end();

不过,我会推荐第一种方法,使用 getSignedUrl() 方法。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。