You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Express(Multer)向Firebase传图失败,报TypeError错误

问题:Firebase后端图片上传报错TypeError: Cannot read properties of undefined (reading 'mimetype')

TypeError: Cannot read properties of undefined (reading 'mimetype')

基于Firebase搭建自定义后端实现图片上传功能时遇到上述错误,移除mimetype属性后仍出现其他属性相关错误,相关代码如下:

index.ts

import * as multer from "multer";

// dotenv.config();
const app = express();
initializeApp(firebaseConfig);
// admin.initializeApp(functions.config().functions);
admin.firestore();

export const openai = new OpenAIApi(configuration);
export const upload = multer({storage: multer.memoryStorage()});

app.use(bodyParser.json());
app.use(express.urlencoded({extended: false}));
app.use(cors({origin: true}));

routesConfig(app);
export const api = functions.https.onRequest(app);

route

export function routesConfig(app: Application) {
  app.get("/", (req, res) => res.status(200).send("Welcome home!!!"));
  // registrations api---------------------------------------------------

  app.post("/verifyuser", upload.single("name"), verifyUserAccount);

}

verifyUserAccount函数

export async function
verifyUserAccount(req: Request, res: Response): Promise<Response<unknown>> {
  try {
    const dd = await Uploading.uploadData( req.body.files, "gbenga", "gbenga");
    // const data = dataAuthService;
    return res.status(200).send({message: "Succesfull", dd});
  } catch (error) {
    logger.error("error is coming from wher" + error);
    return res.status(400).send(error);
  }
}

Uploading.uploadData类

import { getStorage, ref, uploadBytesResumable } from "firebase/storage";
import { logger } from "firebase-functions/v1";
import { injectable } from "inversify";

@injectable()
export class Uploading {
   static async uploadData(file:any, userId:string, postId:string): Promise<string> {
    const bucket = getStorage();
    // const bucketDomain = "gs://uneleap-9b858.appspot.com";
    try {
      const dateTime = Date.now();
      const fileName = `${postId}/${userId}/${dateTime}`;
      const storageRef = ref(bucket, fileName);
      const metadata = {
          contentType: file.mimetype,
      };
      await uploadBytesResumable(storageRef, file.buffer, metadata);
      return fileName;
    //     // const subPaths = file.fieldname.split("/");
    //     // const fileName = subPaths[subPaths.length - 1];
    //     const destination = `${postId}/${userId}/${postId}`;
    //     await bucket.bucket().upload(file.path, { destination, resumable: true });
    //     const uploadedUrl = `https://${bucketDomain}/${destination}`; // Construct the URL\
    //     const uploadedImageLinks = await Promise.all(uploadedUrl);
    // return uploadedImageLinks;
    } catch (error) {
      logger.error("Error =>", error);
      throw new Error("this is from error");
    }
  }

}

解决方案

错误核心原因

使用multer.single()解析文件后,文件对象不会存放在req.body中,而是挂载到req.file上。当前传递的req.body.files是undefined,导致后续访问file.mimetype触发报错。

具体修改步骤

  1. 修正文件获取方式
    修改verifyUserAccount函数,将req.body.files替换为req.file,同时增加文件存在性校验:

    export async function verifyUserAccount(req: Request, res: Response): Promise<Response<unknown>> {
      try {
        // 校验是否有文件上传
        if (!req.file) {
          return res.status(400).send({ message: "请上传文件" });
        }
        const dd = await Uploading.uploadData(req.file, "gbenga", "gbenga");
        return res.status(200).send({ message: "成功", dd });
      } catch (error) {
        logger.error("错误来源:" + error);
        return res.status(400).send(error);
      }
    }
    
  2. 确认字段名一致性
    路由中upload.single("name")的参数"name"是前端上传文件的表单字段名,必须和前端保持一致。比如前端文件输入框的name属性要设为name:

    <input type="file" name="name" />
    

    如果前端用其他字段名(如avatar),需同步修改路由参数为upload.single("avatar")。

  3. 前端请求格式校验
    前端发送请求时必须设置Content-Type为multipart/form-data,否则multer无法解析文件。

内容的提问来源于stack exchange,提问作者Gbenga B Ayannuga

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 21:25:02