无法使用Firebase功能将图像上传到Firebase存储

这是我的代码:-

exports.uploadImage = (req,res) => {

    const BusBoy = require('busboy');
    const path = require('path');
    const os = require('os');
    const fs = require('fs');

    const busboy = new BusBoy({ headers: req.headers });

    let imageFileName;
    let imageToBeUploaded = {};

    busboy.on('file',(fieldname,file,filename,encoding,mimetype) => {

        const imageExtension = filename.split('.')[filename.split('.').length - 1];
        imageFileName = `${Math.round(Math.random() * 100000000000)}.${imageExtension}`;
        const filepath = path.join(os.tmpdir(),imageFileName);
        imageToBeUploaded = { filepath,mimetype };
        file.pipe(fs.createWriteStream(filepath));

    });

    busboy.on('finish',() => {

        console.log('Busboy on started');    

        //code breaks here    
        admin.storage().bucket().upload(imageToBeUploaded.filepath,{
            resumable: false,metadata: {
                metadata: {
                    contentType: imageToBeUploaded.mimetype
                }
            }
        })
        .then(() => {
            const imageUrl = `https://firebasestorage.googleapis.com/v0/b/${config.storageBucket}/o/${imageFileName}?alt=media`;
            console.log('logging image url' + imageUrl);
            return db.doc(`/users/${req.user.handle}`).update({ imageUrl })
        })
        .then(() => {
            return res.json({ message: 'Image uploaded successfully' });
        })
        .catch(err => {
            console.error(err);
            return res.status(500).json({ error: err.code });
        })
    });
    busboy.end(req.rawBody);
}

我已经提到我的代码在注释中出现的地方,而我得到的错误是Error: Cannot parse response as JSON: Not Found message: 'Cannot parse response as JSON: Not Found'

错误消息说无法将响应解析为JSON。这是否意味着Firebase的响应不是JSON?我在请求的标题中有一个令牌,在主体中有一个图像作为表单数据。我真的不知道怎么了,请帮忙

zjfshy 回答:无法使用Firebase功能将图像上传到Firebase存储

很不幸,我无法识别JSON解析错误,因此我改写了代码,以简化@robsiemb的工作。

您的uploadImage函数似乎已配置为某些中间件,因此我在下面做了同样的事情。该代码将使用从Reference.push().key生成的唯一文件名将上传的数据直接流到Cloud Storage,以防止冲突。

在下面的代码中,

  • 上载的文件将存储在类似于userData/someUserId/images/-JhLeOlGIEjaIOFHR0xd.png
  • 的位置
  • 图像的原始URL未存储在数据库中,因为除非将文件对象或包含存储桶公开,否则它将需要一个signed URL,它只能持续7天(见下文)。
  • 可以接受并上传多个文件。如果不希望这样,请配置limits for the BusBoy instance
  • 添加了用于非POST请求和缺少文件条目的基本错误处理。
// import Firebase libraries & initialize
const admin = require('firebase-admin');
admin.initializeApp(); // initializes from environment variables

// import required modules
const BusBoy = require('busboy');

exports.uploadImage = (req,res) => {
    if (req.method !== 'POST') {
      res.sendStatus(405); // 405 METHOD_NOT_ALLOWED
      return;
    }

    let busboy = new BusBoy({headers: req.headers}); // add {limits: {files: 1}} to limit to only a single file upload
    let bucket = admin.storage().bucket();
    let db = admin.firestore();

    let storageFilepath;
    let storageFile;

    // Note: Currently only the last file is saved to `/users/${req.user.handle}`
    busboy.on('file',(fieldname,file,filename,encoding,mimetype) => {
        let fileext = filename.match(/\.[0-9a-z]+$/i)[0];

        storageFilepath = `userData/${req.user.handle}/images/` + getUniqueName() + fileext;
        storageFile = bucket.file(storageFilepath);

        file.pipe(storageFile.createWriteStream({ gzip: true }));
    })
    .on('finish',() => {
      if (!storageFile) {
        res.status(400).json({error: 'expected file'}); // 400 BAD_REQUEST
        return;
      }

      db.doc(`/users/${req.user.handle}`).update({ imagePath: storageFilepath })
        .then(() => {
            res.status(201).json({ message: 'Image uploaded successfully' }); // 201 CREATED
        })
        .catch((err) => {
          console.error(err);
          res.status(500).json({ error: err.code }); // 500 INTERNAL_SERVER_ERROR
        });
    })
    .on('error',(err) => {
      console.error(err);
      res.status(500).json({ error: err.code });
    });

    req.pipe(busboy);
});

function getUniqueName() {
  // push() without arguments returns a ThennableReference,which we'll abuse for it's key generation
  return admin.database().ref().push().key;
}

如果您确实希望公开访问上传的图像,则可以使用以下.on('finish',...)处理程序,该处理程序添加到File.makePublic()函数中:

.on('finish',() => {
  if (!storageFile) {
    res.status(400).json({error: 'expected file'}); // 400 BAD_REQUEST
    return;
  }

  storageFile.makePublic()
    .then(() => {
      return db.doc(`/users/${req.user.handle}`).update({
          imagePath: storageFilepath,imageUrl: `https://storage.googleapis.com/${config.storageBucket}/${storageFilepath}`
        });
    })
    .then(() => {
        res.status(201).json({ message: 'Image uploaded successfully' }); // 201 CREATED
    })
    .catch((err) => {
      console.error(err);
      res.status(500).json({ error: err.code }); // 500 INTERNAL_SERVER_ERROR
    });
})
,

找到了解决该问题的方法!

本质上-您需要设置Google应用程序凭据。进入firebase并查看您的设置。您需要设置环境变量GOOGLE_APPLICATION_CREDENTIALS,以便在访问这些文件时firebase拥有您的凭据。

https://firebase.google.com/docs/admin/setup?authuser=1了解更多信息。

完成此操作后,请检查Firebase中您要处理的每个区域的安全设置。这应该可以解决问题(绝对是安全问题,而不是您的代码)。

对于那些关注的人来说,这也是该教程。 https://www.youtube.com/watch?v=m_u6P5k0vP0&t=7661s

,

在我的情况下,它配置了错误的存储桶 ID - 更正后我能够上传文件

本文链接:https://www.f2er.com/3137172.html

大家都在问