Node.js+Firebase Functions:解决Firebase Storage文件附SendGrid邮件空白问题
解决Firebase Storage文件通过SendGrid发送后PDF空白的问题
问题出在你对二进制文件的Buffer处理逻辑上,原代码中Buffer.from(file, 'binary')的编码参数会破坏从Firebase Storage获取的二进制数据,最终导致PDF内容丢失、仅显示空白页面。
修复方案
直接修改sendEmailWithAttachment函数中的附件内容处理代码,移除'binary'编码参数:
const sendEmailWithAttachment = async (file, filename, type, disposition) => { const attachments = [ { content: Buffer.from(file).toString('base64'), // 移除'binary'参数 filename: filename || 'file.pdf', type: type || 'application/pdf', disposition: disposition || 'attachment', }, ] try { await sendEmail({ to: 'goodbye@goodbye.com', template: 'welcome', dynamic_template_data: { subject: 'Welcome To World', businessName: 'World', action_url: '', }, attachments: attachments, }) } catch (error) { console.log(error) } }
原因说明
通过Axios获取的response.data是ArrayBuffer类型,Buffer.from(file)会直接将ArrayBuffer转换为正确的Buffer对象,再转成base64编码就能保证二进制数据完整。而指定'binary'参数时,Node.js会错误地把ArrayBuffer当成二进制字符串解析,导致字节数据错乱,最终PDF无法正常显示内容。
额外优化(可选)
如果不想通过下载URL获取文件,直接用Firebase Admin SDK读取Storage文件更可靠,能避免HTTP请求的潜在问题:
- 安装依赖:
npm install firebase-admin
- 修改
index.js中的文件获取逻辑:
const functions = require('firebase-functions') const { sendEmail } = require('./libs/sendgrid') const admin = require('firebase-admin') admin.initializeApp() exports.userOnCreate = functions.firestore .document('users/{userId}') .onCreate(async (snap, context) => { const data = snap.data() const { filePath } = data // 传入Firebase Storage的文件路径,例如"users/xxx/file.pdf" if (filePath) { try { const file = await getFileFromStorage(filePath) await sendEmailWithAttachment(file, 'file.pdf', 'application/pdf', 'attachment') } catch (error) { console.log(error) } } }) const getFileFromStorage = async (filePath) => { try { const bucket = admin.storage().bucket() const file = bucket.file(filePath) const [buffer] = await file.download() return buffer } catch (error) { console.error('Error fetching file:', error) throw error } } // sendEmailWithAttachment函数使用上面修复后的版本
内容的提问来源于stack exchange,提问作者jonthornham
相关产品推荐
相关产品推荐

