我正在尝试将图片从我的Cordova应用程序上传到新的Firebase Storage。这就是我迄今为止所尝试的。
// 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 Storage所需的Javascript文件或Blob格式的图像?谢谢!
不喜欢将XMLHhttpRequest用于本地文件,因此在使用Cordova文件插件后,我终于可以工作了。希望它对某人有所帮助!
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));
}
}
正如@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);
上面山姆的链接将我引向了正确的方向。这是一个可行的解决方案。
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
});
});
}
我遇到了同样的问题。解决方案8
在这里如何使用文件路径HTML5创建/初始化文件对象
像魔术一样工作。
如果你的文件上传字段设置为multiple=true
那么你将得到一个对象数组,所以你必须选择你需要上传的对象。这可能会对你有所帮助
var uploadTask = storageRef.child('images/' + file[0].name).put(file[0]);
安格斯·布雷姆纳,
我试图实施您的解决方案并失败了。我没有收到错误并且"成功"我设法重新获得函数"图像数据",即:"内容://媒体/外部/图像/媒体/3384"。有什么建议吗?
要使用 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);
});
};