简体   繁体   English

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

[英]Uploading image to Firebase Storage from Cordova app

I am trying to upload an image from my Cordova app to the new Firebase Storage. 我正在尝试将我的Cordova应用程序中的图像上传到新的Firebase存储。 This is what I have attempted so far. 这是我到目前为止所尝试的。

 // 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); }); } ) }; 

This results in the following error 这会导致以下错误

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

One other thing I have tried is getting the image as base64 and converting to a Blob, but same result. 我尝试过的另一件事是将图像作为base64并转换为Blob,但结果相同。

Does anyone one know how to get the image in the Javascript File or Blob formats that Firebase Storage requires? 有谁知道如何以Firebase存储所需的Javascript文件或Blob格式获取图像? Thanks! 谢谢!

Didn't like to use XMLHhttpRequest for a local file so after playing with Cordova File Plugin I finally got it working. 不喜欢将XMLHhttpRequest用于本地文件,因此在使用Cordova File Plugin之后我终于开始工作了。 Hope it helps someone! 希望它可以帮到某人!

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));
}

} }

As @juanwmedia stated in his answer, I don't like to use XMLHhttpRequest for a local file, so here it is his answer without the use of ngCordova, just plain cordova-plugin-file: 正如@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);

The link from Sam above led me in the right direction. Sam上面的链接让我朝着正确的方向前进。 Here is a working solution. 这是一个有效的解决方案。

 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 }); }); } 

I had the same issue. 我遇到过同样的问题。 Solution no. 解决方案号 8 in here 8在这里

how to create/initialize the file object using file path html5 如何使用文件路径html5创建/初始化文件对象

works like magic. 像魔术一样工作。

if your file upload field is set to multiple=true then you will get array of objects so you have to choose which one you need to upload. 如果您的文件上传字段设置为multiple=true那么您将获得对象数组,因此您必须选择需要上传的对象。 this may help you 这可能对你有帮助

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

Angus Bremner, 安格斯·布雷姆纳

I tried to implement your solution and failed. 我试图实施你的解决方案但失败了。 I do not get error and "onSucess" I manage to regain function "imageData" that is : "content: // media / external / images / media / 3384". 我没有得到错误和“onSucess”我设法恢复功能“imageData”,即:“content:// media / external / images / media / 3384”。 Any suggestions? 有什么建议么?

To upload multiple images using ionic and firebase: 要使用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);
    });


};

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM