Firebase-Admin无法上传图片至Firebase问题求助
解决Multer + Firebase Functions本地调试时的"Unexpected end of form"错误
问题重现
使用Firebase Admin、Node.js、Express和Multer实现图片上传至Firebase Storage,本地通过firebase serve启动模拟器,用Postman测试/uploadImage接口时,持续抛出以下错误:
Error: Unexpected end of form > at Multipart._final (/Users/user/Desktop/FitStop-Functions/functions/node_modules/busboy/lib/types/multipart.js:588:17) > at prefinish (node:internal/streams/writable:906:14) > at finishMaybe (node:internal/streams/writable:920:5) > at Writable.end (node:internal/streams/writable:835:5) > at onend (node:internal/streams/readable:946:10) > at process.processTicksAndRejections (node:internal/process/task_queues:77:11)
上传核心代码如下:
const functions = require("firebase-functions"); const app = require("express")(); const { bucket } = require("./util/admin"); const multer = require("multer"); const storage = multer.memoryStorage(); const upload = multer({ storage: storage, limits: { fileSize: 8 * 1024 * 1024 }, fileFilter: (req, file, cb) => { if (!file.originalname.match(/\.(jpg|jpeg|png)$/)) { return cb(new Error("Only image files are allowed!"), false); } cb(null, true); }, }); app.post("/uploadImage", upload.single("file"), async (req, res) => { console.log(req.file); if (!req.file) { return res.status(400).send("No file uploaded."); } const fileName = `uploads/${Date.now()}_${req.file.originalname}`; try { const fileUpload = bucket.file(fileName); const blobStream = fileUpload.createWriteStream({ metadata: { contentType: req.file.mimetype, }, }); blobStream.on("error", (error) => { console.error("Blob stream error:", error); return res.status(500).json({ error: error.message }); }); blobStream.on("finish", async () => { await fileUpload.makePublic(); const publicUrl = `https://storage.googleapis.com/${bucket.name}/${fileName}`; res.status(200).json({ message: "File uploaded successfully", url: publicUrl, }); }); blobStream.end(req.file.buffer); } catch (error) { console.error("Upload error:", error); res.status(500).json({ error: "Internal server error" }); } }); exports.api = functions.https.onRequest(app);
核心原因
Firebase Functions本地模拟器(firebase serve)默认会自动解析所有请求体,包括multipart/form-data格式的请求。这会导致Multer依赖的Busboy无法获取完整的原始表单数据,从而触发"Unexpected end of form"错误。
解决方案
方案1:禁用Firebase Functions的自动请求体解析
修改函数导出代码,添加rawBody: true配置,让Firebase Functions保留原始请求体,交给Multer处理:
exports.api = functions.https.onRequest({ rawBody: true }, app);
方案2:调整Postman请求配置
确保Postman的请求设置正确,避免手动干扰表单解析:
- 请求方法选择
POST - Body类型选择
form-data - 表单键名设置为
file(与代码中upload.single("file")的参数一致) - 对应值选择「File」类型,上传符合要求的图片文件(jpg/jpeg/png)
- 不要手动设置
Content-Type请求头,让Postman自动生成带边界标识的multipart/form-data头
方案3:排查依赖版本冲突
如果上述方案无效,可能是Multer与Busboy的版本不兼容:
- 尝试降级Multer到稳定版本:
npm install multer@1.4.5-lts.1 - 清除node_modules和package-lock.json,重新安装依赖:
rm -rf node_modules package-lock.json npm install
内容的提问来源于stack exchange,提问作者lamb p
相关产品推荐
相关产品推荐

