使用Multer上传文件时遇TypeError: next is not a function错误求助
解决Multer + Firebase Functions中出现的TypeError: next is not a function
嘿,我碰到过一模一样的问题,这其实是Multer中间件的设计逻辑和Firebase Functions的HTTP回调参数不匹配导致的,咱们一步步来解决:
问题根源
Multer是专门为Express框架做的中间件,它默认期望接收三个参数:req, res, next。但Firebase的functions.https.onRequest只会给回调函数传前两个参数。当你直接把upload.single('license')当成onRequest的回调时,Multer内部尝试调用next(),但这个参数根本不存在,自然就抛出了TypeError: next is not a function的错误。
解决方案
这里有两种实用的解决办法,你可以根据自己的习惯选:
方案1:手动包装Multer中间件
把Multer的调用包裹在你的请求处理函数里,手动传入一个next函数(哪怕是空函数,只要是个合法函数就行):
const {Storage} = require('@google-cloud/storage') const multer = require('multer'); const functions = require('firebase-functions'); // 配置Google Cloud Storage const storage = new Storage({ projectId: functions.config().project.id }) const bucket = storage.bucket(functions.config().bucket.url) // Multer配置 const upload = multer({ storage: multer.memoryStorage(), limits:{ fileSize: 5 * 1024 * 1024 // 限制文件大小不超过5MB } }) exports.updateUserRole = functions.https.onRequest((req, res) => { // 手动调用Multer中间件,传入自定义的next函数 upload.single('license')(req, res, (err) => { if (err) { return res.status(400).send(`上传失败:${err.message}`); } // 检查是否有文件被上传 if (!req.file) { return res.status(400).send('请选择要上传的文件'); } // 将文件上传到Google Cloud Storage const file = bucket.file(req.file.originalname); const stream = file.createWriteStream({ metadata: { contentType: req.file.mimetype } }); stream.on('error', (err) => { return res.status(500).send(`文件存储失败:${err.message}`); }); stream.on('finish', () => { return res.status(200).send('文件上传成功!'); }); stream.end(req.file.buffer); }); });
方案2:用Express托管请求处理
如果你的项目有多个HTTP端点,或者更习惯Express的写法,直接把Express应用集成到Firebase Functions里,这样就能像普通Express项目一样用Multer了:
const {Storage} = require('@google-cloud/storage') const multer = require('multer'); const functions = require('firebase-functions'); const express = require('express'); const app = express(); // 配置Google Cloud Storage const storage = new Storage({ projectId: functions.config().project.id }) const bucket = storage.bucket(functions.config().bucket.url) // Multer配置 const upload = multer({ storage: multer.memoryStorage(), limits:{ fileSize: 5 * 1024 * 1024 // 限制文件大小不超过5MB } }) // 定义Express路由,直接使用Multer中间件 app.post('/updateUserRole', upload.single('license'), (req, res) => { if (!req.file) { return res.status(400).send('请选择要上传的文件'); } const file = bucket.file(req.file.originalname); const stream = file.createWriteStream({ metadata: { contentType: req.file.mimetype } }); stream.on('error', (err) => { return res.status(500).send(`文件存储失败:${err.message}`); }); stream.on('finish', () => { return res.status(200).send('文件上传成功!'); }); stream.end(req.file.buffer); }); // 将Express应用导出为Firebase函数 exports.updateUserRole = functions.https.onRequest(app);
为什么之前没问题?
你之前长期用Multer没出错,应该是在普通的Express项目里使用的——那里的路由回调会自动把next参数传递给中间件,自然不会触发这个错误。迁移到Firebase Functions后,回调参数的变化就暴露了这个兼容性问题。
内容的提问来源于stack exchange,提问作者bogere goldsoft
相关产品推荐
相关产品推荐

