Firebase Cloud Functions中node-canvas的registerFont无法解析字体报错问题
问题原因
你遇到的报错不是Firebase平台的兼容性问题,核心原因是云存储文件下载操作是异步逻辑,你没有等待下载完成就调用了字体注册方法:
bucket.file('tnr.ttf').download()方法返回的是Promise对象,你的现有代码会直接向下执行registerFont,此时临时路径下的字体文件还没有完成写入,要么为空要么内容不完整,自然无法被node-canvas解析。
修复方案
将回调逻辑改为async异步写法,等待下载完成后再执行字体注册,同时补全错误处理逻辑,修复后的代码参考如下:
const fs = require('fs/promises'); exports.test = functions.https.onRequest(async (request, response) => { try { await new Promise((resolve, reject) => { cors(request, response, (err) => err ? reject(err) : resolve()); }); const tempFilePath = path.join(os.tmpdir(), 'tnr.ttf'); functions.logger.log('tempFilePath is', tempFilePath); // 等待字体文件下载完成 await bucket.file('tnr.ttf').download({destination: tempFilePath}); functions.logger.log('Font downloaded locally to', tempFilePath); // 可选:校验文件是否完整,避免下载出错导致的空文件问题 const fileStat = await fs.stat(tempFilePath); if (fileStat.size === 0) { throw new Error('Downloaded font file is empty'); } registerFont(path.resolve(tempFilePath), {family: 'tnr'}); functions.logger.log('Font registered successfully'); // 后续你的图片生成、邮件发送逻辑 response.status(200).send('Success'); } catch (err) { functions.logger.error('Operation failed', err); response.status(500).send('Internal error'); } });
其他注意事项
- 如果你是在Arm架构(如苹果M系列芯片)的设备上本地安装依赖后直接部署,需要先删除本地的
node_modules和package-lock.json/yarn.lock后再执行部署操作,让Firebase云端自动安装匹配Linux x86运行环境的node-canvas二进制包,避免架构不兼容导致的解析错误。 - 确认你使用的字体文件本身没有损坏,可先在本地node环境测试
registerFont可以正常加载该字体文件。
内容的提问来源于stack exchange,提问作者on9_jai
相关产品推荐
相关产品推荐

