TypeError when uploading file to firebase storage node js

Issue

I have a firebase configuration in config.js like – config.js

// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";


const firebaseConfig = {
   apiKey: "..................cTM7iCiI",
   authDomain: "........firebaseapp.com",
   databaseURL: "https://.........-default-rtdb.firebaseio.com",
   projected: "..........",
   storageBucket: "............appspot.com",
   messagingSenderId: "........79191",
   appId: ".......................92",
   measurementId: ".....BL0K"
};

// Initialize Firebase
const firebaseApp = initializeApp(firebaseConfig);

export default firebaseApp;

And a Server.js like –

import express from 'express';
import uploadRouter from './routes/upload.js';

const app = express();

app.use('/upload', uploadRouter);

app.get('/', (req, res) => {
    res.send("Some normal Response!");
});

app.listen(2022);

And I am sending a post request from Postman

and this is my upload.js or A Router js

import { Router } from "express";
import multer from 'multer';

import firebaseApp from "../config.js";
import { getStorage, ref, uploadBytesResumable, getDownloadURL } from "firebase/storage";

const router = Router();

const fileStorageEngine = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, "./uploads");
        // cb(null, path.join(__dirname, '../uploads'));
    },
    filename: (req, file, cb) => {
        cb(null, `${Date.now()}--${file.originalname}`);
    }
});

const multerUpload = multer({ storage: fileStorageEngine });

router.post('/simplefile', multerUpload.single('image'), (req, res) => {
    uploadFile(req, res);
});


function uploadFile(req, res) {
    const file = req.file;

    const storage = getStorage(firebaseApp);

    // Create the file metadata
    /** @type {any} */
    const metadata = {
        contentType: 'image/jpeg'
    };

    // Upload file and metadata to the object 'images/mountains.jpg'
    const storageRef = ref(storage, 'images/' + file.name);
    const uploadTask = uploadBytesResumable(storageRef, file, metadata);

    // Listen for state changes, errors, and completion of the upload.
    uploadTask.on('state_changed',
        (snapshot) => {
            // Get task progress, including the number of bytes uploaded and the total number of bytes to be uploaded
            const progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
            console.log('Upload is ' + progress + '% done');
            switch (snapshot.state) {
                case 'paused':
                    console.log('Upload is paused');
                    break;
                case 'running':
                    console.log('Upload is running');
                    break;
            }
        },
        (error) => {
            switch (error.code) {
                case 'storage/unauthorized':
                    // User doesn't have permission to access the object
                    break;
                case 'storage/canceled':
                    // User canceled the upload
                    break;
                case 'storage/unknown':
                    // Unknown error occurred, inspect error.serverResponse
                    break;
            }
        },
        () => {
            // Upload completed successfully, now we can get the download URL
            getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
                console.log('File available at', downloadURL);
            });
        }
    );
}

export default router;

and this is the error or console log that comes every time I send a post request from postman –

Upload is NaN% done
Upload is running
file:///F:/Websites/MulterPrac/node_modules/@firebase/storage/dist/node-esm/index.node.esm.js:1175
                finalLength += array.byteLength;
                                     ^

TypeError: Cannot read properties of undefined (reading 'byteLength')
    at file:///F:/Websites/MulterPrac/node_modules/@firebase/storage/dist/node-esm/index.node.esm.js:1175:38
    at Array.forEach (<anonymous>)
    at Function.getBlob (file:///F:/Websites/MulterPrac/node_modules/@firebase/storage/dist/node-esm/index.node.esm.js:1174:25)
    at multipartUpload (file:///F:/Websites/MulterPrac/node_modules/@firebase/storage/dist/node-esm/index.node.esm.js:1735:26)
    at file:///F:/Websites/MulterPrac/node_modules/@firebase/storage/dist/node-esm/index.node.esm.js:2379:33
    at file:///F:/Websites/MulterPrac/node_modules/@firebase/storage/dist/node-esm/index.node.esm.js:2283:21
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

any help will be appreciated!

Solution

req.file is a Multer file object. Since you’re using disk storage, you’ll need to read the file into an ArrayBuffer.

import { readFileSync } from "node:fs";

// and later on...
uploadBytesResumable(storageRef, readFileSync(file.path), metadata);

If you don’t actually need to store the file locally, I would recommend using Multer’s MemoryStorage instead

const multerUpload = multer({ storage: multer.memoryStorage() });

// and later on...
uploadBytesResumable(storageRef, file.buffer, metadata);

Answered By – Phil

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published