1

I'm trying to upload video file (14 MB) to google firebase storage using firebase cloud functions, Busboy and node js. But I got following error during file upload. This function works with small files without any issue.

PayloadTooLargeError: request entity too large
   at readStream (C:\Users\User\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\raw-body\index.js:155:17)
   at getRawBody (C:\Users\User\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\raw-body\index.js:108:12)
   at read (C:\Users\User\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\body-parser\lib\read.js:77:3)
   at rawParser (C:\Users\User\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\body-parser\lib\types\raw.js:81:5)
   at Layer.handle [as handle_request] (C:\Users\User\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\layer.js:95:5)
   at trim_prefix (C:\Users\User\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\index.js:317:13)
   at C:\Users\User\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\index.js:284:7
   at Function.process_params (C:\Users\User\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\index.js:335:12)
   at next (C:\Users\User\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\express\lib\router\index.js:275:10)
   at urlencodedParser (C:\Users\User\AppData\Roaming\npm\node_modules\firebase-tools\node_modules\body-parser\lib\types\urlencoded.js:100:7)

These are my code files

index.js

const functions = require("firebase-functions");
const express = require('express');
const FBAuth = require('./util/fbAuth');
const app = express();
const bodyParser = require('body-parser');
const { db } = require("./util/admin");
app.use(express.json({limit: 8 * 1024 * 1024 * 200}));
app.use(express.urlencoded({limit: 8 * 1024 * 1024 * 200}));
const cors = require('cors');

app.use(cors());
app.use(bodyParser.json({limit: 8 * 1024 * 1024 * 200}));
app.use(bodyParser.urlencoded({ limit: 8 * 1024 * 1024 * 200 , extended: true }));

const {
  uploadItem
} = require('./handlers/uploads');

app.post('/upload', FBAuth, uploadItem );

exports.api = functions.https.onRequest(app);

upload.js

const { db, bucket } = require('../util/admin');
const BusBoy = require('busboy');
const path = require('path');
const os = require('os');
const fs = require('fs');
const config = require("../util/config");

exports.uploadItem = (req, res) => {
  console.log('file upload started')
  console.log('data : ' + req.body.name);
  const busboy = BusBoy({headers: req.headers});
  let dataFileName;
  let fileTobeUploaded = {};
  let formData = {};
  busboy.on(
    "field",
    (fieldname, val, fieldnameTruncated, valTruncated, encoding, mimetype) => {
      formData = { ...formData, [fieldname]: val };
    },
  );
  busboy.on('file',(name, file, info) => {
    const { filename, encoding, mimeType } = info;
      //my.image.png
      const fileExtension = filename.split('.')[filename.split('.').length - 1];
      //12345678900.png
      dataFileName = `${Math.round(Math.random()*100000000000)}.${fileExtension}`;
      const filepath = path.join(os.tmpdir(), dataFileName);
      fileTobeUploaded = {filepath, mimeType};
      file.pipe(fs.createWriteStream(filepath)); 
  })
  busboy.on('finish', () => {
    req.body = formData;
      bucket.upload(fileTobeUploaded.filepath, {
          resumable: true,
          metadata:{
              metadata:{
                  contentType:fileTobeUploaded.mimeType
              }
          }
      })
      .then( () => {
        const fileUrl = `https://firebasestorage.googleapis.com/v0/b/${config.storageBucket}/o/${dataFileName}?alt=media`
        const newUpload = {
          uploadItemUrl: fileUrl,
          userHandle: req.user.handle,
          userImage: req.user.imageUrl,
          createdAt: new Date().toISOString(),
          likeCount: 0,
          commentCount: 0
        };
          
        db.collection('uploads').add(newUpload)
      })
      .then( () => {
       
          return res.json({message: "File Uploaded Successfully"});
      })
      .catch(err => {
          console.error(err);
          return res.status(400).json({ error : err.code});
      })
  });
  busboy.end(req.rawBody);
}

Please help me to resolve this. Thank you in advance.

2
  • Hi @Prasad, could you try to increase the limit of your body-parser to like 50mb. app.use(express.json({limit: '50mb'})); app.use(express.urlencoded({limit: '50mb'})); and see if it resolves your issue. Commented Feb 23, 2022 at 4:02
  • @MarcAnthonyB Thanks for your comment. but I still get the same error Commented Feb 23, 2022 at 9:54

1 Answer 1

0

According to Resource Limit Documentation, the maximum data limit can be sent in HTTP Function is 10 mb only for Cloud Function 1st Gen. There is no way to get this limit increased. You could use Cloud Function (2nd gen) to get a 32mb limit instead. You may check the Cloud Function (2nd gen) here.

However, You can still let the client upload directly to storage. Authenticated onto his own user folder and security rules limiting the file size to whatever size you wish into a temp folder. You can use either Google Cloud Storage or Upload files with Cloud Storage on Web.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. I implement direct upload from web.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.