Udendu Abasili
Udendu Abasili

Reputation: 1213

React: Multer image and data upload with using firebase function, node multer

Basically I am using firebase function and hosting with node and react. I can upload image courtesy of How to perform an HTTP file upload using express on Cloud Functions for Firebase (multer, busboy) but how do you upload image and data at the same time?

export const addProduct = (product, imageUrl) => {
  return (dispatch) => {
    return new Promise((resolve, reject) => {
      const fileData = new FormData();
      fileData.append("imageUrl", imageUrl);
      fileData.append("productData", product);
      axios({
        method: "post",
        url: "/api/products/add-product",
        data: fileData,
        headers: {
          "Content-Type": "multipart/form-data",
        },
      });
    });
  };
};

NodeJS

const router = express.Router();
const Busboy = require("busboy");

router.post("/api/products/add-product", async (req, res, next) => {
  if (req.method === "POST") {
    const busboy = new Busboy({ headers: req.headers });
    const uploads = {};
    busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {
      console.log(
        `File [${fieldname}] filename: ${filename}, encoding: ${encoding}, mimetype: ${mimetype}`
      );
    });
  }
});

Upvotes: 0

Views: 434

Answers (1)

Louis Coulet
Louis Coulet

Reputation: 4591

Your client-side code looks OK.
On the server-side you can tell busboy to extract fields as well as files:

const fields = {};
const files = [];
const busboy = new Busboy({headers: req.headers});
busboy.on("field", (key, value) => (fields[key] = value));
busboy.on("file", (fieldname, file, filename, encoding, mimetype) => {/*...*/});
busboy.end(req.rawBoy);

This way you can access fields["productData"] later in your code.

Note that you need to use rawBody to access the unparsed body in Cloud Functions: https://firebase.google.com/docs/functions/http-events#read_values_from_the_request

Upvotes: 2

Related Questions