从Cordova应用程序将图像上传到Firebase存储

时间:2016-05-26 05:43:15

标签: javascript cordova firebase firebase-storage

我正在尝试将图片从我的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格式获取图片?谢谢!

7 个答案:

答案 0 :(得分:6)

Didn不想将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));
}

}

答案 1 :(得分: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);

答案 2 :(得分: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
        });
    });

}




答案 3 :(得分:1)

我有同样的问题。解决方案号8在这里

how to create/initialize the file object using file path html5

就像魔法一样。

答案 4 :(得分:0)

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

var uploadTask = storageRef.child('images/' + file[0].name).put(file[0]);

答案 5 :(得分:0)

Angus Bremner,

我尝试实施您的解决方案但失败了。我没有得到错误和“onSucess”我设法恢复功能“imageData”,即: “content:// media / external / images / media / 3384”。 有什么建议吗?

答案 6 :(得分:0)

使用ionic和firebase上传多个图像:

{{1}}