将本机base64映像上传到Firebase存储

时间:2019-11-28 05:55:31

标签: firebase react-native blob expo

我目前正在开发一个应用程序。我目前拥有的工作流程非常简单。

用户创建一个帐户,然后转到页面以填充其个人资料信息。名称,说明和一些图片。

我使用expo的ImagePicker来获取图片:

    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.Images,
      quality: 0.1,
      allowsEditing: true,
      aspect: [2, 3],
      base64: true
    });

最初,我是用这个来上传图像的:

// Why are we using XMLHttpRequest? See:
    // https://github.com/expo/expo/issues/2402#issuecomment-443726662
    const blob = await new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest();
      xhr.onload = function() {
        resolve(xhr.response);
      };
      xhr.onerror = function(e) {
        reject(new TypeError("Network request failed"));
      };
      xhr.responseType = "blob";
      xhr.open("GET", uri, true);
      xhr.send(null);
    });

    const ref = firebase
      .storage()
      .ref()
      .child(uuid.v4());
    const snapshot = await ref.put(blob);

    // We're done with the blob, close and release it
    blob.close();

    let url = await snapshot.ref.getDownloadURL();

    return url;

这里的问题是我在该函数中循环了大约6次,并且不断出现一些晦涩的错误。

当前,我正在尝试使用以下方式上传图像:

const ref = firebase
      .storage()
      .ref()
      .child(uuid.v4());

    const snapshot = await ref.putString(b64Url, "data_url");

这在网络上效果很好,但是在本机应用程序中,我收到错误消息:

FirebaseStorageError {
  "code_": "storage/invalid-format",
  "message_": "Firebase Storage: String does not match format 'base64': Invalid character found",
  "name_": "FirebaseError",
  "serverResponse_": null,
}

The last comment on this issue概述了问题。对其进行分解:atob不存在。这是错误背后的唯一问题。要修复,我将其填充成这样:

import { decode, encode } from "base-64";

if (!global.btoa) {
  global.btoa = encode;
}

if (!global.atob) {
  global.atob = decode;
}

但是,第二个问题是:

  

Firebase也尝试使用本机Blob类(由react-native实现),但是Blob的react-native版本错误地将Uint8Array数据转换为字符串,从而破坏了上传。

我尝试了deleteglobal.Blob并在上传后恢复它的解决方案。但是, Firebase必须已经依赖于blob,因为现在错误会由于Blob不存在而发生。编辑:实际上,在AppEntry.bundle中某个地方调用了Blob,上传正常。

我希望将我的应用保持在托管的工作流程中,所以我非常希望不要弹出。

我的问题如下:

  1. react-native中特别是破损的Blob代码:
  

不正确地将Uint8Array数据转换为字符串

  1. 有没有一种方法可以避免出错或弹出,同时将6张图片上传到Firebase存储中?如果可以,怎么办?

1 个答案:

答案 0 :(得分:0)

我最终遵循的解决方案是:

  async function uploadImageAsync(uri) {
    const ref = firebase
      .storage()
      .ref()
      .child(uuid.v4());

    const blob = await new Promise((resolve, reject) => {
      const xhr = new XMLHttpRequest();
      xhr.onload = function() {
        resolve(xhr.response);
      };
      xhr.onerror = function() {
        reject(new TypeError("Network request failed"));
      };
      xhr.responseType = "blob";
      xhr.open("GET", uri, true);
      xhr.send(null);
    });

    var mimeString = uri
      .split(",")[0]
      .split(":")[1]
      .split(";")[0];

    const snapshot = await ref.put(blob, { contentType: mimeString });

    let url = await snapshot.ref.getDownloadURL();

    return url;
  }

我发现我似乎无法使Firebase的putString函数正常工作,但是我可以使用XMLHttpRequest从字符串中创建一个Blob。然后我将Blob上传到Firebase