来自 node-canvas 的 registerFont() 未在 Firebase Cloud Functions 上解析字体

registerFont() from node-canvas not parsing font on Firebase Cloud Functions

我目前正致力于通过 Firebase Cloud Functions 使用 node-canvas 生成图像,然后使用 nodemailer.

将其作为电子邮件附件发送

图像的要求是我需要将一些字符串输入到具有特定字体的模板中。

所以在 Firebase Cloud Functions 上,这是我所做的:

exports.test = functions.https.onRequest((request, response) => {
  cors(request, response, () => {
      let tempFilePath = path.join(os.tmpdir(), 'tnr.ttf');
      functions.logger.log('tempFilePath is', tempFilePath);

      bucket.file('tnr.ttf').download({destination: tempFilePath});
      functions.logger.log('Font downloaded locally to', tempFilePath);

      registerFont(path.resolve(tempFilePath), {family: 'tnr'});
      functions.logger.log('Font registered successfully');
  }
}

我已经反复验证文件 'tnr.ttf' 存在于我的项目云中并且可以成功加载到该临时路径。

然而,在 registerFont 函数中,无论我使用哪个字体文件,Firebase 总是会抛出这个错误:

Error: Could not parse font file
    at registerFont (/workspace/node_modules/canvas/index.js:48:17)

Firebase 处理这个包或函数的方式可能有问题吗?

您正在尝试在字体下载完成之前使用它。当您意识到问题时,打开终端并确认它确实存在,下载已完成。

您需要做的是等待 download(...) 返回的 Promise 解决或将回调附加到 download() 方法。然后下载完成后,就可以注册字体了。

exports.test = functions.https.onRequest((request, response) => {
  cors(request, response, (corsErr) => {
    if (corsErr) {
      // this is rare, but still possible.
      functions.logger.error('Request rejected by CORS: ', corsErr);
      res.status(412).send('Rejected by CORS'); // 412 FAILED PRECONDITION
      return;
    }

    let tempFilePath = path.join(os.tmpdir(), 'tnr.ttf');
    functions.logger.log('tempFilePath is ', tempFilePath);

    bucket.file('tnr.ttf').download(
      {destination: tempFilePath},
      (err) => {
        if (err) {
          functions.logger.error('Failed to download font to local system: ', err);
          res.status(422).send('Failed to register font'); // 422 UNPROCESSABLE ENTITY
          return;
        }

        functions.logger.log('Font downloaded locally to ', tempFilePath);

        registerFont(path.resolve(tempFilePath), {family: 'tnr'});
        functions.logger.log('Font registered successfully');

        res.send('Registered font successfully');
      }
    );
  }
}

备注:

  • 不要忘记正确处理错误并正确终止请求。
  • 可能会再次调用相同的函数调用,请考虑在某处设置“我已经下载了那个”标志。在“最坏情况”下,您最终可能会得到 100 个相同的字体文件。
  • 确保在您将要使用它的地方执行 registerFont 方法。你不能有单独的 /registerFonts/drawWithFont 端点,因为你不能保证与刚才的同一个函数实例对话。