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 存储桶。如果我以blobUint8Array 发送它,当我在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 上的本地路径加载图像

react-native - 图像需要来自 JSON 的本地路径

React Native - 图像缓存

React Native - 缓存图像