开发者问题收集

TypeError:无法使用 nodejs 读取未定义的属性“byteLength”

2021-05-01
5210

I am not able to understand why firebase is not accepting the image, the following message is appearing: TypeError: Cannot read property 'byteLength' of undefined

我尝试将 'byteLength' 值添加到我的对象 (req.file),但同样的错误仍然存​​在。

下面是我的实现

const firebase2 = require('firebase/app');
require('firebase/storage');


router.put('/addimage', multer.single('picture'), async (req, res, next) => {
   const newName = uuidv1() + "-" + req.file.originalname;
   var storageRef = firebase2.storage().ref('photo/'+ newName);
   storageRef.put(req.file);  
});

在此处输入图像描述

这个 html 示例我确实有效。我想制作一个后端,所以我正在迁移到 nodejs

<html>
<head>
    <meta charset="utf-8">
    <title>Teste</title>
    <style>
        body {
            display: flex;
            min-height: 100vh;
            width: 100%;
            padding: 0;
            margin: 0;
            align-items: center;
            justify-content: center;
            flex-direction: column;
        }
        #uploader {
            -webkit-appearance: none;
            appearance: none;
            width: 50%;
            margin-bottom: 10%;
        }
    </style>
</head>
<body>
    <progress value="0" max="100" id="uploader">0%</progress>
    <input type="file" value="upload" id="fileButton"></input>

    <script src="https://gstatic.com/firebasejs/live/3.0/firebase.js"></script>
    <script>
        // Your web app's Firebase configuration
        // For Firebase JS SDK v7.20.0 and later, measurementId is optional
        var firebaseConfig = {
          apiKey: "xxxxx",
          authDomain: "xxxxx",
          projectId: "xxxxx",
          storageBucket: "xxxxxxx",
          messagingSenderId: "xxxxxx",
          appId: "xxxxxxx",
          measurementId: "xxxxxx"
        };
        // Initialize Firebase
        firebase.initializeApp(firebaseConfig);

        var uploader = document.getElementById('uploader');
        var fileButton = document.getElementById('fileButton');

        fileButton.addEventListener('change', function(e){

            var file = e.target.files[0];

            var storageRef = firebase.storage().ref('sweet_fifs/'+ file.name);

            var task = storageRef.put(file);

            task.on('state_changed', 
                function progress(snapshot) {
                    var percetage = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
                    uploader.value = percetage;
                },
                function error(err) {

                }
            )

        });
        
      </script>
</body>
2个回答

Reference#put 方法需要将 Blob | Uint8Array | ArrayBuffer 作为其第一个参数。您提供的 req.file 对象不属于上述任何一种。但是,我们可以看到 Buffer 对象可用作 req.file 对象的属性,并且该缓冲区中的内容类型也是如此。因此,我们需要做的就是提取这些值并将它们传递给 Reference#put() 。另外,不要忘记为用户创建响应并处理任何错误。

router.put('/addimage', multer.single('picture'), async (req, res, next) => {
   const newName = uuidv1() + "-" + req.file.originalname;
   const storageRef = firebase2.storage().ref('photo/'+ newName);
   
   storageRef.put(req.file.buffer, {
     contentType: req.file.mimetype
   })
   .then(() => storageRef.getDownloadURL()) // after upload, obtain the download URL
   .then(
     (url) => {
       // persisted to storage successfully and obtained download URL
       res
         .status(201)
         .set("Content-Location", url) // use "Location" if you want to redirect to it
         .json({
           "message": "Upload successful"
         });
     },
     (err) => {
       // failed to save to storage
       logger.error({
         message: "Upload failed with error",
         errorMessage: err.message,
         errorStack: err.stack
       });

       res
         .status(500)
         .json({
           "message": "Upload failed",
           "error": err.code || "unknown"
         });
     }
   )
   .catch((err) => {
     // if here, something has gone wrong while sending back the response
     // likely a syntax error, or sending responses multiple times
     logger.error({
       message: "Unexpected rejection during /addImage",
       errorMessage: err.message,
       errorStack: err.stack
     });
   });
});
samthecodingman
2021-05-01

发生这种情况有两个原因,其一,

当中间件中未定义 缓冲区 时发生。由于在您的示例代码中我没有看到中间件,因此我无法假设,因此应该是这样的。

const multer = require('multer')

//storage middleware
const storage = multer.memoryStorage();
      
const upload = multer({ storage: storage });

第二个原因是您访问 Firebase 的方式。更好的方法是

const { initializeApp } = require("firebase/app"); 
const{ref,getDownloadURL,uploadBytesResumable}=
require('firebase/storage');
const { firebaseConfig, storage } = require('../firebase');
// Initialize a firebase application
initializeApp(firebaseConfig);

然后访问所有内容:

const time = Date.now();
const file = req.file;

//const firebaseFilePath = `images/${time + file.filename}`;
const storageRef = ref(storage, `images/${time + file.filename}`);

const metadata = {
 contentType: req.file.mimetype,
};

// Upload the file in the bucket storage
console.log('Array:', req.file.buffer);

const snapshot = await uploadBytesResumable(
  storageRef,
  req.file.buffer,
  metadata
);

// Grab the public url
const downloadURL = await getDownloadURL(snapshot.ref);

这是我导入的文件:

const { initializeApp } = require("firebase/app");
const { getStorage } = require('firebase/storage');

const firebaseConfig = {
  apiKey: ***,
  authDomain: ***,
  projectId: ***,
  storageBucket: ***,
  messagingSenderId: ***,
  appId: ***,
  measurementId: ***
};

// Initialize Firebase
const app = initializeApp(firebaseConfig);
const storage = getStorage(app);

module.exports = { firebaseConfig, storage };
nathanaelmbale
2023-04-08