当前位置: 首页 > 知识库问答 >
问题:

如何使用pdfmake生成pdf,并使用firebase云功能将其存储在firebase存储中[重复]

何星鹏
2023-03-14

我正在firebase中开发一个应用程序。创建订单时,我希望生成其发票。我已经实现了这个功能,但是URL有问题,因为pdf是创建的,但是正如你在图片中看到的,打开它的URL是错误的。

这是我在云函数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, 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创建正确,但网址是错误的,我不能打开它。

如果有人帮助我,我将非常感激。

共有1个答案

郭俊拔
2023-03-14

这是通过管理SDK将文件上载到云存储时的已知问题,请参阅https://github.com/firebase/firebase-admin-node/issues/694.

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

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

如果要使用第二个选项(尽管似乎不建议这样做),则以下方法可以解决问题:

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();

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

 类似资料:
  • 我正在学习firebase,有一些关于Firebase存储的问题: < li >我可以使用的总文件大小的限制? < li >我想使用firebase datastorage使用avatar上传图像,然后使用该url将图像加载到带有glide或picasso的imageview。可能吗? < li >我想将我的应用程序与firebase authenticate配合使用,以使用登录、firebase

  • null 云存储桶是云功能工作所必需的吗?如果没有,我怎么能回到这些变化发生之前的地方。请引导我。

  • 我的firebase cloud函数包含受保护的路由,只有在请求头中传递有效的IdToken时才能访问这些路由。云函数API如下所示 最初,我使用Firebase身份验证创建新用户并获取IdToken 我可以使用Auth emulator UI创建新用户,但是如何生成这些用户的访问令牌呢?是否有任何APIendpoint可以返回本地保存的用户的IdToken,这样我就可以测试受保护的API,而无需

  • 我有一个使用Firebase身份验证的node.js客户端。现在我想访问谷歌云存储,但是node.js的Firebase SDK不包括GCS。使用@google-云/存储工作,但只有匿名访问。如何将Firebase凭据应用到@google-Cloud/存储,以便在登录用户的上下文中访问GCS?

  • 但是如何使用Firebase来使用不由Firebase管理的现有存储桶(尽管它拥有与创建Firebase应用程序所使用的相同的谷歌云账户的管理员访问权限)?

  • 然后我更改了流,在sendOrderEmail函数中,我还从bucket中新创建的文件打开一个新的读取流。 现在我在附件中至少得到了PDF的一些内容,但从来没有完整的内容。 当我检查上传到bucket的PDF时,它看起来应该。 null null 谁能告诉我我做错了什么,或者提供一个工作的例子,它使用当前的包版本,为这个用途? 这是让我抓狂的代码...