2

我正在尝试将图像从我的 Cordova 应用程序上传到新的 Firebase 存储。这是我迄今为止所尝试的。

// Get the image from PhotoLibrary
navigator.camera.getPicture(onSuccess, onFail, { 
  quality: quality,
  sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
  destinationType: Camera.DestinationType.FILE_URI,
  targetWidth: imageSize,
  targetHeight: imageSize
});

function onSuccess(imageData) {
  
  var storageRef = firebase.storage().ref();
  
  window.resolveLocalFileSystemURL(imageData,
	function(fileEntry) {
	  fileEntry.file(function(file) {
          var uploadTask = storageRef.child('images/test.jpg').put(file);
          uploadTask.on('state_changed', function(snapshot){
	    console.log(snapshot);
          });
	}                     
   )
};

这会导致以下错误

FirebaseError: Firebase Storage: Invalid argument in `put` at index 0: Expected Blob or File.

我尝试过的另一件事是将图像获取为 base64 并转换为 Blob,但结果相同。

有谁知道如何获取 Firebase 存储所需的 Javascript 文件或 Blob 格式的图像?谢谢!

4

7 回答 7

6

不喜欢将 XMLHhttpRequest 用于本地文件,所以在玩了Cordova File Plugin之后,我终于让它工作了。希望它可以帮助某人!

function MainController($scope, $cordovaCamera, $cordovaFile) {
$scope.capturarFoto = function (type) {
    var opcionesCaptura = {
        destinationType: Camera.DestinationType.FILE_URI,
        sourceType: Camera.PictureSourceType[type.toUpperCase()],
    };

    $cordovaCamera.getPicture(opcionesCaptura)
        .then(procesarImagen, procesarError);
};

function procesarImagen(pathImagen) {
    var directorioFuente = pathImagen.substring(0, pathImagen.lastIndexOf('/') + 1),
        archivoFuente = pathImagen.substring(pathImagen.lastIndexOf('/') + 1, pathImagen.length),
        nombreParaGuardar = new Date().valueOf() + archivoFuente;

    $cordovaFile.readAsArrayBuffer(directorioFuente, archivoFuente)
        .then(function (success) {
            var blob = new Blob([success], {type: 'image/jpeg'});
            enviarFirebase(blob, nombreParaGuardar);
        }, function (error) {
            console.error(error);
        });
}


function enviarFirebase(file, nombre) {
    var storageRef = firebase.storage().ref();
    var uploadTask = storageRef.child('images/' + nombre).put(file);
    uploadTask.on('state_changed', function (snapshot) {
        console.info(snapshot);
    }, function (error) {
        console.error(error);
    }, function () {
        var downloadURL = uploadTask.snapshot.downloadURL;
        console.log(downloadURL);
    });
}

function procesarError(error) {
    console.error(JSON.stringify(error));
}

}

于 2016-06-08T08:40:55.323 回答
6

正如@juanwmedia 在他的回答中所说,我不喜欢将 XMLHhttpRequest 用于本地文件,所以这是他不使用 ngCordova 的回答,只是普通的 cordova-plugin-file:

navigator.camera.getPicture(function (imageUri) {
          window.resolveLocalFileSystemURL(imageUri, function (fileEntry) {
             fileEntry.file(function (file) {
                 var reader = new FileReader();
                 reader.onloadend = function () {
                          // This blob object can be saved to firebase
                          var blob = new Blob([new Uint8Array(this.result)], { type: "image/jpeg" });                  
                          sendToFirebase(blob);
                 };
                 reader.readAsArrayBuffer(file);
              });
          }, function (error) {
              errorCallback(error);
          });
       }, errorCallback, options);
于 2016-07-19T12:00:50.140 回答
3

上面 Sam 的链接将我引向了正确的方向。这是一个有效的解决方案。

navigator.camera.getPicture(onSuccess, onFail, {
    quality: quality,
    sourceType: Camera.PictureSourceType.PHOTOLIBRARY,
    destinationType: Camera.DestinationType.FILE_URI,
    targetWidth: imageSize,
    targetHeight: imageSize
});

function onSuccess(imageData) {

    var storageRef = firebase.storage().ref();

    var getFileBlob = function(url, cb) {
        var xhr = new XMLHttpRequest();
        xhr.open("GET", url);
        xhr.responseType = "blob";
        xhr.addEventListener('load', function() {
            cb(xhr.response);
        });
        xhr.send();
    };

    var blobToFile = function(blob, name) {
        blob.lastModifiedDate = new Date();
        blob.name = name;
        return blob;
    };

    var getFileObject = function(filePathOrUrl, cb) {
        getFileBlob(filePathOrUrl, function(blob) {
            cb(blobToFile(blob, 'test.jpg'));
        });
    };

    getFileObject(imageData, function(fileObject) {
        var uploadTask = storageRef.child('images/test.jpg').put(fileObject);

        uploadTask.on('state_changed', function(snapshot) {
            console.log(snapshot);
        }, function(error) {
            console.log(error);
        }, function() {
            var downloadURL = uploadTask.snapshot.downloadURL;
            console.log(downloadURL);
            // handle image here
        });
    });

}

于 2016-06-01T05:14:26.827 回答
1

我遇到过同样的问题。解决方案编号 8在这里

如何使用文件路径 html5 创建/初始化文件对象

像魔术一样工作。

于 2016-06-01T04:19:04.647 回答
0

如果您的文件上传字段设置为,multiple=true那么您将获得对象数组,因此您必须选择需要上传的对象。这可能会帮助你

var uploadTask = storageRef.child('images/' + file[0].name).put(file[0]);
于 2016-05-27T02:19:24.930 回答
0

安格斯·布雷姆纳,

我试图实施您的解决方案但失败了。我没有收到错误并且“onSucess”我设法重新获得功能“imageData”,即:“内容://媒体/外部/图像/媒体/3384”。有什么建议么?

于 2016-06-14T18:07:44.880 回答
0

使用 ionic 和 firebase 上传多张图片:

$scope.upload = function(sourceType) {

 var options = {
        quality : 75,
        destinationType : Camera.DestinationType.FILE_URI,
        sourceType : sourceType,
        encodingType: Camera.EncodingType.JPEG,
        popoverOptions: CameraPopoverOptions,
        targetWidth: 500,
        targetHeight: 500,
        saveToPhotoAlbum: false
    };
    $cordovaCamera.getPicture(options).then(function(imageData) {

 // $scope.images = imageData;

 var storageRef = firebase.storage().ref();
 // filename = imageData.name;

var getFileBlob = function(url, cb) {
    var xhr = new XMLHttpRequest();
    xhr.open("GET", url);
    xhr.responseType = "blob";
    xhr.addEventListener('load', function() {
        cb(xhr.response);
    });
    xhr.send();
};

var blobToFile = function(blob, name) {
    blob.lastModifiedDate = new Date();
    blob.name = name;
    return blob;
};

var getFileObject = function(filePathOrUrl, cb) {
    getFileBlob(filePathOrUrl, function(blob) {
        cb(blobToFile(blob, new Date().getTime()));
    });
};

getFileObject(imageData, function(fileObject) {

    var metadata = {
    'contentType': fileObject.type
  };
    storageRef.child('images/' + fileObject.name).put(fileObject, metadata);

    uploadTask.on('state_changed', null, function(error) {
    // [START onfailure]
    console.error('Upload failed:', error);
    alert('Upload failed:', error);
    // [END onfailure]
  }, function() {
    console.log('Uploaded',uploadTask.snapshot.totalBytes,'bytes.');
    console.log(uploadTask.snapshot.metadata);
    var url = uploadTask.snapshot.metadata.downloadURLs[0];
    console.log('File available at', url);
    // [START_EXCLUDE]
    document.getElementById('linkbox').innerHTML = '<img src="' +  url + '">';
    // [END_EXCLUDE]
  });

});
    }, function(error) {
        console.error(error);
        alert(error);
    });


};
于 2016-07-27T08:16:13.860 回答