React Native-将图像从本地缓存发送到Firebase存储

时间:2018-12-01 11:19:47

标签: react-native firebase-storage

在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的形式工作?这是代码:

作为斑点

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,
 }

1 个答案:

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