I'm trying to upload a file to the OpenAI API using Firebase Cloud Functions, Express and Multer. I have a React UI that I'm using to upload a file to my back end to then send to the OpenAI API, but I'm stuck on an issue with Multer. Whenever I try to upload a file through my React UI Multer either doesn't receive it or errors:
Error: unexpected end of form
I want to be able to see the file and any other request parameters that I send to the endpoint in the console debug statements. My back end code:
import {onRequest} from "firebase-functions/v2/https";
import express from "express";
import cors from "cors";
import multer from "multer";
const app = express();
app.use(cors({origin: true}));
app.use(express.json());
app.use(express.urlencoded({extended: true}));
// Multer memory storage
const storage = multer.memoryStorage();
const upload = multer({storage: storage});
// Healthcheck endpoint
app.get("/healthcheck", (req, res) => {
res.status(200).json({
status: "ok",
timestamp: new Date().toISOString(),
message: "Backend is running",
});
});
// Parse file endpoint
app.post("/parse-file", upload.single("uploadFile"), async (req, res) => {
console.log("Content-Type:", req.headers);
console.log("File received:", req.file); // Currently only seeing undefined
console.log("Body:", req.body); // Currently only seeing {} but I want to see any params I pass to it such as { uid: "123456" }
res.json({ok: true, body: req.body});
return;
});
export const api = onRequest(app);
UI code:
import axios from "axios"
import React, { useState } from "react"
const UploadDocument: React.FC = () => {
const [file, setFile] = useState<File | undefined>(undefined)
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
if (!file) return;
const formData = new FormData();
formData.append("uploadFile", file);
formData.append("uid", user?.uid || "test"); // Replace with real UID later
axios
.post("MY_BACKEND_URL/api/parse-file", formData)
.then((response) => {
console.log("Backend response:", response.data);
})
}
return (
<form onSubmit={handleSubmit}>
<input type="file" name="uploadFile" onChange={(e) => setFile(e.target.files?.[0])} />
<button type="submit">Send to OpenAI</button>
</form>
)
}
If I use the most recent stable version of Multer I see:
Error: unexpected end of form.
If I use Multer v1.4.2 or v1.4.3 the API returns {ok: true, body: {}} saying the file was undefined. Other fields I pass to the endpoint do not show up either (like the uid field in the UI or a test field, the body is empty).
In my back end I've tried moving app.use(express.json()) after and before creation of the endpoint. Using Busboy directly instead of Multer returns:
Error: unexpected end of form
upload.single("uploadFile") matches. Different versions of Firebase functions didn't change the result. Hitting the endpoint manually through Postman instead of my UI got the same results. I'm assuming it's not a CORS issue. In my UI adding headers manually for multipart/form-data received the same result. Adding the file name to formData like formData.append("uploadFile", file, file.name) received the same result.
How can I upload a file to the OpenAI API?