使用 Node.js 和 Firebase cloudstore 在 Cloud Functions 中生成并通过电子邮件发送 pdf
Generate & email pdf in Cloud Functions using Node.js and Firebase cloudstore
我在云函数中有以下代码,只要用户下订单就会触发。然后我想使用 firebase 存储生成 pdf 格式的发票,然后通过电子邮件将 pdf 发送给用户。我很难生成 pdf,因为我不确定我应该怎么做。下订单后,电子邮件会毫无问题地发送给用户。我知道如何在下面的邮件选项中制作附件,但我不知道如何创建 pdf 并插入产品信息。
// Triggers once the user place an order
exports.notifyUserOfOrderConfirmation = functions.firestore.document('masterOrders/{masterOrderId}').onCreate((snap, context) => {
const data = snap.data();
const orderedUserEmail = data.userEmail;
const customerOrderId = data.customerOrderId;
const userId = data.userId;
const masterOrderId = context.params.masterOrderId;
return orderProductsQuery(data, masterOrderId, orderedUserEmail, customerOrderId, userId)
});
// Query the firestore to get the ordered products
function orderProductsQuery(data, masterOrderId, orderedUserEmail, customerOrderId, userId) {
return db.collection('users').doc(userId).collection('orders').doc(customerOrderId).collection('orderCart').get().then(snap => {
const orderedProducts = [];
snap.forEach(doc => {
const productData = doc.data();
orderedProducts.push(productData);
})
// return notifyUserOfOrderConfirmation(data, masterOrderId, orderedUserEmail, customerOrderId, orderedProducts)
return generatePDF(data, masterOrderId, orderedUserEmail, customerOrderId, orderedProducts)
}).catch((err) => {
console.log('Error getting documents', err);
return Promise.reject(err);
})
}
这是我需要帮助的地方;下面的代码是我到目前为止写的:
const pdfkit = require("pdfkit");
const Storage = require('@google-cloud/storage');
// Creates a client
const storage = new Storage ({projectId: MYPROJECTID});
// Lists all buckets in the current project
const buckets = storage.getBuckets();
function generatePDF(data, masterOrderId, orderedUserEmail, customerOrderId, orderedProducts) {
const doc = new pdfkit();
const filename = `/${customerOrderId}/test-` + Date.now() + '.pdf';
const bucket = storage.bucket(MYBUCKETNAME)
const file = bucket.file(filename);
const bucketFileStream = file.createWriteStream();
doc.pipe(bucketFileStream);
doc.end();
bucketFileStream.on('finish', function () {
return notifyUserOfOrderConfirmation(filename, data, masterOrderId, orderedUserEmail, customerOrderId, orderedProducts)
});
bucketFileStream.on("error", function (err) {
console.error(err);
});
}
这是我发送电子邮件的时间;我知道下面的这段代码在没有 pdf 代码的情况下也能正常工作,所以在没有 pdf 的情况下发送电子邮件没有问题:
async function notifyUserOfOrderConfirmation(filename, data, masterOrderId, orderedUserEmail, customerOrderId, orderedProducts) {
const bucket = storage.bucket(MYBUCKETNAME);
const file = bucket.file(filename);
const mailOptions = {
from: `${APP_NAME} <MYEMAIL>`,
to: orderedUserEmail
};
mailOptions.subject = `Order Confirmation`;
mailOptions.text = `We received your order. attached is your invoice`;
mailOptions.attachments = [{
filename: "test.pdf",
content: file.createReadStream()
}];
await transporter.sendMail(mailOptions);
console.log('New welcome email sent to:', orderedUserEmail);
return null;
}
当我部署它时;我的部署没有错误。但是当我在应用程序中下订单时;我在 firebase 的函数中收到以下错误:
Error: socket hang up
at TLSSocket.onHangUp (_tls_wrap.js:1148:19)
at Object.onceWrapper (events.js:313:30)
at emitNone (events.js:111:20)
at TLSSocket.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:139:11)
at process._tickDomainCallback (internal/process/next_tick.js:219:9)
Unhandled rejection
知道这里的问题是什么以及我如何在这种情况下正确生成 pdf 吗?
想通了。上面的代码实际上是正确的,我只是在这里有一个错误的文件名 const file = bucket.file(filename);
所以这段代码没有问题,对于任何想使用它来创建 pdf 和电子邮件给用户的人来说,它就像一个魅力。
我在云函数中有以下代码,只要用户下订单就会触发。然后我想使用 firebase 存储生成 pdf 格式的发票,然后通过电子邮件将 pdf 发送给用户。我很难生成 pdf,因为我不确定我应该怎么做。下订单后,电子邮件会毫无问题地发送给用户。我知道如何在下面的邮件选项中制作附件,但我不知道如何创建 pdf 并插入产品信息。
// Triggers once the user place an order
exports.notifyUserOfOrderConfirmation = functions.firestore.document('masterOrders/{masterOrderId}').onCreate((snap, context) => {
const data = snap.data();
const orderedUserEmail = data.userEmail;
const customerOrderId = data.customerOrderId;
const userId = data.userId;
const masterOrderId = context.params.masterOrderId;
return orderProductsQuery(data, masterOrderId, orderedUserEmail, customerOrderId, userId)
});
// Query the firestore to get the ordered products
function orderProductsQuery(data, masterOrderId, orderedUserEmail, customerOrderId, userId) {
return db.collection('users').doc(userId).collection('orders').doc(customerOrderId).collection('orderCart').get().then(snap => {
const orderedProducts = [];
snap.forEach(doc => {
const productData = doc.data();
orderedProducts.push(productData);
})
// return notifyUserOfOrderConfirmation(data, masterOrderId, orderedUserEmail, customerOrderId, orderedProducts)
return generatePDF(data, masterOrderId, orderedUserEmail, customerOrderId, orderedProducts)
}).catch((err) => {
console.log('Error getting documents', err);
return Promise.reject(err);
})
}
这是我需要帮助的地方;下面的代码是我到目前为止写的:
const pdfkit = require("pdfkit");
const Storage = require('@google-cloud/storage');
// Creates a client
const storage = new Storage ({projectId: MYPROJECTID});
// Lists all buckets in the current project
const buckets = storage.getBuckets();
function generatePDF(data, masterOrderId, orderedUserEmail, customerOrderId, orderedProducts) {
const doc = new pdfkit();
const filename = `/${customerOrderId}/test-` + Date.now() + '.pdf';
const bucket = storage.bucket(MYBUCKETNAME)
const file = bucket.file(filename);
const bucketFileStream = file.createWriteStream();
doc.pipe(bucketFileStream);
doc.end();
bucketFileStream.on('finish', function () {
return notifyUserOfOrderConfirmation(filename, data, masterOrderId, orderedUserEmail, customerOrderId, orderedProducts)
});
bucketFileStream.on("error", function (err) {
console.error(err);
});
}
这是我发送电子邮件的时间;我知道下面的这段代码在没有 pdf 代码的情况下也能正常工作,所以在没有 pdf 的情况下发送电子邮件没有问题:
async function notifyUserOfOrderConfirmation(filename, data, masterOrderId, orderedUserEmail, customerOrderId, orderedProducts) {
const bucket = storage.bucket(MYBUCKETNAME);
const file = bucket.file(filename);
const mailOptions = {
from: `${APP_NAME} <MYEMAIL>`,
to: orderedUserEmail
};
mailOptions.subject = `Order Confirmation`;
mailOptions.text = `We received your order. attached is your invoice`;
mailOptions.attachments = [{
filename: "test.pdf",
content: file.createReadStream()
}];
await transporter.sendMail(mailOptions);
console.log('New welcome email sent to:', orderedUserEmail);
return null;
}
当我部署它时;我的部署没有错误。但是当我在应用程序中下订单时;我在 firebase 的函数中收到以下错误:
Error: socket hang up
at TLSSocket.onHangUp (_tls_wrap.js:1148:19)
at Object.onceWrapper (events.js:313:30)
at emitNone (events.js:111:20)
at TLSSocket.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:139:11)
at process._tickDomainCallback (internal/process/next_tick.js:219:9)
Unhandled rejection
知道这里的问题是什么以及我如何在这种情况下正确生成 pdf 吗?
想通了。上面的代码实际上是正确的,我只是在这里有一个错误的文件名 const file = bucket.file(filename);
所以这段代码没有问题,对于任何想使用它来创建 pdf 和电子邮件给用户的人来说,它就像一个魅力。