React Native - 将图像从本地缓存发送到 Firebase 存储
Posted
技术标签:
【中文标题】React Native - 将图像从本地缓存发送到 Firebase 存储【英文标题】:React Native - send image from local cache to firebase storage 【发布时间】:2019-05-03 08:39:19 【问题描述】:在 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?代码如下:
作为 blob
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数据的url
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,
【问题讨论】:
【参考方案1】:我们在尝试检索图片并将其发送到 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);
));
【讨论】:
以上是关于React Native - 将图像从本地缓存发送到 Firebase 存储的主要内容,如果未能解决你的问题,请参考以下文章
如何从 URL 下载图像并缓存 Android (React-Native)
预加载、缓存 gif 图像以避免在 React Native 中闪烁
React Native - 如何从 WebView 上的本地路径加载图像