在Android上使用React Native时,我正在尝试将用户的图像配置文件从本地缓存发送到Firebase存储桶。如果我以blob
或Uint8Array
的形式发送,则在firebase上打开图像时会收到错误The image "https://firebasestorage<resto of url here>" cannot be displayed because it contain errors
。如果我以base64 data url
的形式发送,则不会将其上传到存储桶,并且收到消息Firebase Storage: String does not match format 'base64': Invalid character found
。我已经使用解码器测试了base64数据url,并且可以正常工作。我怎样才能使其以blob,Uint8Array或base64的形式工作?这是代码:
作为斑点
let mime = 'image/jpeg';
getFile(imageUri)
.then(data => {
return new Blob([data], { type: mime });
})
.then(blob => {
return imageRef.put(blob, { contentType: mime });
})
async function getFile(imageUri) {
let bytes = await FileSystem.readAsStringAsync(imageUri);
return Promise.resolve(bytes);
}
作为Uin8Array
let mime = 'image/jpeg';
getFile(imageUri)
.then(data => {
return imageRef.put(data, { contentType: mime });
})
async function getFile(imageUri) {
let bytes = await FileSystem.readAsStringAsync(imageUri);
const imageBytes = new Uint8Array(bytes.length);
for ( let i = 0; i < imageBytes.length; i++) {
imageBytes[i] = bytes.charCodeAt(i);
}
return Promise.resolve(imageBytes);
}
作为base64数据网址
imageBase64Url = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAADCAIAAADZSiLoAAAAF0lEQVQI12P8//8/AwMDAwMDEwMMIFgAVCQDA25yGkkAAAAASUVORK5CYII=";
return imageRef.putString(imageBase64Url, 'data_url');
URI
我从该对象检索uri:
Object {
"cancelled": false,
"height": 60,
"type": "image",
"uri": "file:///data/user/0/host.exp.exponent/cache/ExperienceData/%2540anonymous%252FMCC_Project-ee81e7bd-82b1-4624-8c6f-8c882fb131c4/ImagePicker/6ec14b33-d2ec-4f80-8edc-2ee501bf6e92.jpg",
"width": 80,
}
答案 0 :(得分:0)
我们尝试检索图片并将其发送到Firebase存储桶的方式至少发现了两个问题:
1)从内存中检索图像并尝试将其作为blob
发送到存储桶时,FileSystem.readAsStringAsync(imageUri)
由于某种原因返回了损坏的文件
2)相反,当尝试将图像以base64
的形式保存到Firebase存储桶时,问题似乎出在firebase上,因为https://firebase.google.com/docs/storage/web/upload-files此处提供的示例都不起作用。
解决方案:
我们使用XMLHttpRequest
(而不是Expo的FileSystem
)从本地缓存中检索了图像,并将其另存为blob
到Firebase存储桶中:
import React, { Component } from 'react';
import firebase from './firebase';
export default async function saveImage(picture, uid) {
const storageRef = firebase
.storage('gs://*<bucket-here>*')
.ref(uid + '/' + 'profile-picture.jpeg');
const blob = await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onload = function() {
resolve(xhr.response);
};
xhr.onerror = function(e) {
console.log(e);
reject(new TypeError('Network request failed'));
};
xhr.responseType = 'blob';
xhr.open('GET', picture.uri, true);
xhr.send(null);
});
const metadata = {
contentType: 'image/jpeg',
};
return (downloadURL = await new Promise((resolve, reject) => {
try {
storageRef.put(blob, metadata).then(snapshot => {
snapshot.ref.getDownloadURL().then(downloadURL => {
resolve(downloadURL);
});
});
} catch (err) {
reject(err);
}
}));
}