来自 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
端点,因为你不能保证与刚才的同一个函数实例对话。
我目前正致力于通过 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
端点,因为你不能保证与刚才的同一个函数实例对话。