将多个图像blob从离子1上传到firebase 3

时间:2022-04-06 22:58:30

I can upload a single image converted to a blob to firebase 3 successfully. However, when I try to upload multiple images to firebase 3 from my ionic 1 app, it fails.

我可以成功地将转换为blob的单个图像上传到firebase 3。但是,当我尝试从我的离子1应用程序上传多个图像到firebase 3时,它失败了。

The console logs that the data was successfully uploaded. I cannot see it in the firebase storage UI. I only see the first image I selected.

控制台记录数据已成功上载。我在firebase存储UI中看不到它。我只看到我选择的第一张图片。

This is the code that gets the images:

这是获取图像的代码:

  $scope.getImages = function () {
  var options = {
    maximumImagesCount: 10,
    width: 1000,
    height: 1000,
    quality: 100
  };

  $cordovaImagePicker.getPictures(options)
    .then(function (results) {
      for (var i = 0; i < results.length; i++) {
        $scope.selectedImages.push(results[i]);
        var fileName = results[i].replace(/^.*[\\\/]/, '');

        // the image storage path is different on android
        var path = '';
        if ($ionicPlatform.is("android")) {
          path = cordova.file.cacheDirectory;
        }
        else {
          path = cordova.file.tempDirectory;
        } // end of android image rectification 

        $cordovaFile.readAsArrayBuffer(path, fileName)
          .then(function (realImage) {
            var imageBlob = new Blob([realImage], { type: "image/jpeg" });

            imgUpload(imageBlob, fileName)

          })
      }

    }, function (error) {
      // error getting photos
      console.log(error.name);
    })

Below is the code for firebase service

以下是firebase服务的代码

function imgUpload(_imgBlob, _filename) {

  var uploadsMetadata = {
    cacheControl: "max-age=" + (60 * 60 * 24 * 365) // One year of seconds
  };

  //create the storage reference and use it to access
  var storeRef = firebase.storage().ref();



  var uploadTask = storeRef.child('images/' + _filename).put(_imgBlob, uploadsMetadata);

  return new Promise(function (resolve, reject) {
    uploadTask.on('state_changed', function (snap) {
      console.log('Progress: ', snap.bytesTransferred, '/', snap.totalBytes, ' bytes');
    }, function (err) {
      console.log('upload error', err);
      reject(err);
    }, function () {
      var metadata = uploadTask.snapshot.metadata;
      var key = metadata.md5Hash.replace(/\//g, ':');
      var fileRecord = {
        downloadURL: uploadTask.snapshot.downloadURL,
        key: key,
        metadata: {
          fullPath: metadata.fullPath,
          md5Hash: metadata.md5Hash,
          name: metadata.name
        }
      };

      // uploadsRef.child(key).set(fileRecord).then(resolve, reject);
    });
  }); // end of Promise


  // return snapshot;
}  // end of function imgUpload

1 个解决方案

#1


0  

[Edited 2/15/2017]

Padrian, without knowing what your specific error(s) were in the code above I can only assume that your issue(s) are the same as what was dealing with, namely that the metadata.md5Hash was failing since the metadata wasn't defined. My code and your code are nearly identical barring the UI framework differences.

Padrian,在不知道上面的代码中你的具体错误是什么我只能假设你的问题与正在处理的问题相同,即metadata.md5Hash失败,因为没有定义元数据。除了UI框架差异外,我的代码和代码几乎相同。

My first refactoring to remove the error was to removed the listening on events and went with just having a callback on the .put() like so:

我第一次删除错误的重构是删除了对事件的监听,并且只是在.put()上进行了回调,就像这样:

storageRef.child(uploadFile.name).put(uploadFile).then(cb(snap)).catch(errCB(err))

I further refactored my code and just as mysteriously as there was an issue, there was no longer an issue. Below is my full code for processing the upload file. I placed the code inside an async.queue so I could limit the file uploads to 4 files at a time.

我进一步重构了我的代码,就像有问题一样神秘,不再是问题。以下是我处理上传文件的完整代码。我将代码放在async.queue中,这样我就可以一次将文件上传限制为4个文件。

const q = async.queue(function (file, callback) {
  let reader = new window.FileReader()

  reader.onload = function (e) {
    const tags = ExifReader.load(e.target.result)
    if (tags['Orientation'].description === 'left-bottom') {
      file.rotation = 'rotate(-90deg)'
    }
  }

  reader.readAsArrayBuffer(file.file.slice(0, 128 * 1024))

  let uploadTask = storageRef.child(file.file.name).put(file.file, uploadsMetadata)
  file.uploadSuccess = false
  file.uploadError = false
  file.active = 'active'

  uploadTask.on('state_changed',
    function (snap) {
      file.progress = snap.bytesTransferred / snap.totalBytes * 100
    },
    function (err) {
      file.uploadError = true
      file.errorMessage = err
      callback(err)
    },
    function () {
      let metadata = uploadTask.snapshot.metadata
      let key = metadata.md5Hash.replace(/\//g, ':')
      let pendingInventoryRecord = {
        downloadURL: uploadTask.snapshot.downloadURL,
        key: key,
        metadata: {
          fullPath: metadata.fullPath,
          md5Hash: metadata.md5Hash,
          name: metadata.name
        },
        style: file.invStyle,
        size: file.invSize,
        count: file.invCount,
        rotate: file.rotation || ''
      }
      uploadRef.child(key).set(pendingInventoryRecord)
      .then(function () {
        pendingInventoryCountRef.child('counter').transaction(function (currentVal) {
          return (currentVal || 0) + 1
        })

        callback(null, file)
      })
      .catch(function (err) { console.log(err) })
    })
}, 4)

#1


0  

[Edited 2/15/2017]

Padrian, without knowing what your specific error(s) were in the code above I can only assume that your issue(s) are the same as what was dealing with, namely that the metadata.md5Hash was failing since the metadata wasn't defined. My code and your code are nearly identical barring the UI framework differences.

Padrian,在不知道上面的代码中你的具体错误是什么我只能假设你的问题与正在处理的问题相同,即metadata.md5Hash失败,因为没有定义元数据。除了UI框架差异外,我的代码和代码几乎相同。

My first refactoring to remove the error was to removed the listening on events and went with just having a callback on the .put() like so:

我第一次删除错误的重构是删除了对事件的监听,并且只是在.put()上进行了回调,就像这样:

storageRef.child(uploadFile.name).put(uploadFile).then(cb(snap)).catch(errCB(err))

I further refactored my code and just as mysteriously as there was an issue, there was no longer an issue. Below is my full code for processing the upload file. I placed the code inside an async.queue so I could limit the file uploads to 4 files at a time.

我进一步重构了我的代码,就像有问题一样神秘,不再是问题。以下是我处理上传文件的完整代码。我将代码放在async.queue中,这样我就可以一次将文件上传限制为4个文件。

const q = async.queue(function (file, callback) {
  let reader = new window.FileReader()

  reader.onload = function (e) {
    const tags = ExifReader.load(e.target.result)
    if (tags['Orientation'].description === 'left-bottom') {
      file.rotation = 'rotate(-90deg)'
    }
  }

  reader.readAsArrayBuffer(file.file.slice(0, 128 * 1024))

  let uploadTask = storageRef.child(file.file.name).put(file.file, uploadsMetadata)
  file.uploadSuccess = false
  file.uploadError = false
  file.active = 'active'

  uploadTask.on('state_changed',
    function (snap) {
      file.progress = snap.bytesTransferred / snap.totalBytes * 100
    },
    function (err) {
      file.uploadError = true
      file.errorMessage = err
      callback(err)
    },
    function () {
      let metadata = uploadTask.snapshot.metadata
      let key = metadata.md5Hash.replace(/\//g, ':')
      let pendingInventoryRecord = {
        downloadURL: uploadTask.snapshot.downloadURL,
        key: key,
        metadata: {
          fullPath: metadata.fullPath,
          md5Hash: metadata.md5Hash,
          name: metadata.name
        },
        style: file.invStyle,
        size: file.invSize,
        count: file.invCount,
        rotate: file.rotation || ''
      }
      uploadRef.child(key).set(pendingInventoryRecord)
      .then(function () {
        pendingInventoryCountRef.child('counter').transaction(function (currentVal) {
          return (currentVal || 0) + 1
        })

        callback(null, file)
      })
      .catch(function (err) { console.log(err) })
    })
}, 4)