如何解决如何使用 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 错误,我无法打开它。
如果有人帮助我,我将不胜感激。
解决方法
这是通过 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 举报,一经查实,本站将立刻删除。