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

Firebase云功能-创建pdf,存储到bucket并通过邮件发送

云锦
2023-03-14

然后我更改了流,在sendOrderEmail函数中,我还从bucket中新创建的文件打开一个新的读取流。

现在我在附件中至少得到了PDF的一些内容,但从来没有完整的内容。

当我检查上传到bucket的PDF时,它看起来应该。

    null
    null

谁能告诉我我做错了什么,或者提供一个工作的例子,它使用当前的包版本,为这个用途?

这是让我抓狂的代码...

const functions = require("firebase-functions");
const admin = require("firebase-admin");
const nodemailer = require("nodemailer");
const pdfkit = require("pdfkit");
const storage = require("@google-cloud/storage")({projectId: `${PROJECT_ID}`})

const mailTransport = nodemailer.createTransport({
  host: "smtp.office365.com",
  port: 587,
  secureConnection: false,
  auth: {
    user: "userName",
    pass: "userPassword"
 },
 tls: {
   ciphers: "SSLv3",
 }
});

exports.added = function(event) {
  const order = event.data.val();
  const userId = event.params.userId;

  // Load User Data by userId
  return admin
       .database()
       .ref("/users/" +userId)
       .once("value")
       .then(function (snapshot) {
               return generateOrderPDF(snapshot.val(), userId);
       });
};

function generateOrderPDF(user, userId) {
  const doc = new pdfkit();
  const bucket = storage.bucket(functions.config().bucket);
  const filename =  `/${userId}/test-` + Date.now() + ".pdf";
  const file = bucket.file(filename);
  const bucketFileStream = file.createWriteStream();

  // Pipe its output to the bucket
  doc.pipe(bucketFileStream);

 // Do creation Stuff....

  doc.end();

  bucketFileStream.on("finish", function () {
    return sendOrderEmail(user, filename);
  });

  bucketFileStream.on("error", function(err) {
    console.error(err);
  });
}

function sendOrderEmail(user, filename) {
  const email = user.email;
  const firstname = user.firstName;
  const mailOptions = {
    from: "test@test.test",
    to: email,
    subject: "Order"
  };

  const bucket = storage.bucket(functions.config().bucket);
  const file = bucket.file(filename);

  mailOptions.html = mailTemplate;
  mailOptions.attachments =  [{
    filename: "test.pdf",
    content: file.createReadStream()
  }];

  return mailTransport.sendMail(mailOptions).then(() => {
    console.log("New order email sent to:", email);
  }).catch(error => {
    console.error(error);
  });
}

共有1个答案

谷翰飞
2023-03-14

我的appraoch中的问题是在pdfkit库中,而不是在nodemailer或Firebase中。下面的行似乎触发了结束事件。所以pdf是在这些行之后发送的。在对他们发表评论之后,一切都正常进行。这并不是像哈里提到的那样,没有达到终点。

/*  doc.lineCap("underline")
    .moveTo(72, 321)
    .lineTo(570, 321)
    .stroke();*/

在完成MVP后,我将采取一个根本原因分析,并张贴最后的答案作为评论在这个答案下面。

这是一个用于此用途的源代码的工作示例。它还确保firebase函数不会在所有工作完成之前完成。这是通过将事件驱动的doc.on()函数包装到一个promise中来处理的,该promise是在调用doc.on(“end”)时解析的。

exports.added = function(event) {
  const order = event.data.val();
  const userId = event.params.userId;

  // Load User Data by userId
  return admin.database().ref("/users/" + userId).once("value").then(function (snapshot) {
    return generatePDF(snapshot.val(), userId);
  });
};

function generatePDF(user, userId) {
  const doc = new pdfkit();
  const bucket = admin.storage().bucket(functions.config().moost.orderbucket);
  const filename =  "/${userId}/attachement.pdf";
  const file = bucket.file(filename);
  const bucketFileStream = file.createWriteStream();
  var buffers = [];
  let p = new Promise((resolve, reject) => {
    doc.on("end", function() {
      resolve(buffers);
    });
    doc.on("error", function () {
      reject();
    });
  });

  doc.pipe(bucketFileStream);
  doc.on('data', buffers.push.bind(buffers));

  //Add Document Text and stuff

  doc.end();

  return p.then(function(buffers) {
     return sendMail(buffers);
  });
}

function sendMail(buffers) {
  const pdfData = Buffer.concat(buffers);
  const mailOptions = {
    from: "FromName <from@example.com>",
    to: "to@example.com",
    subject: "Subject",
    html: mailTemplate,
    attachments: [{
      filename: 'attachment.pdf',
      content: pdfData
    }]
  };

  return mailTransport.sendMail(mailOptions).then(() => {
    console.log("New email sent to:", "to@example.com");
  }).catch(error => {
    console.error(error);
  });
}
 类似资料:
  • 我是一个python开发人员。我们使用GCS(Google cloud storage)来存储我们过去几个月的图像,这很好,但对于android来说,它需要将所有桶导入Firebase cloud storage(FCS)来访问它。我们不想要任何手动集成。我们听说,如果我们在FCS上创建一个bucket,自动反映到GCS,这是好的,不需要导入。 我们试图直接在firebase云存储上创建bucke

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

  • 错误:(gcloud.functions.deploy)operationerror:code=7,message=没有足够的权限(重新)配置触发器(bucket ing-auto权限被拒绝)。请将所有者权限授予bucket的编辑器角色,然后再试一次。 对于云中使用的服务帐户,函数拥有对bucket所在项目的所有者访问权限。 也就是说,有两个项目,project-a和Project-B。需要在Pr

  • 错误消息: 未配置账单帐户。外部网络无法访问,配额受到严重限制。配置帐单帐户以删除这些限制 编辑1: 1。我目前正在使用nodemailer发送邮件。 2。我使用Gmail作为邮件服务。

  • 问题内容: 我在向我的收件箱(Gmail帐户)发送邮件时遇到问题,但是每次都转到垃圾邮件文件夹时。这是代码片段 我尝试过很多类似将标头设置为Reply-To,Return-Path等的方法,但是每次都将其转为垃圾邮件时。你能找出问题所在吗? 问题答案: 问题很简单,PHP-Mail功能没有使用配置良好的SMTP服务器。 如今,电子邮件客户端和服务器会对电子邮件发送服务器进行大量检查,例如反向DNS

  • 原因:com.google.api.client.googlejsonresponseException:401未经授权{“代码”:401,“错误”:[{“域”:“全局”,“位置”:“授权”,“位置类型”:“标头”,“消息”:“匿名调用者没有Storage.Buckets.List access to project 833568054484.”,“原因”:“必需”}],“消息”:“匿名调用者没有