【问题标题】:Firebase Storage v3 returning "multipart body does not contain 2 or 3 parts" on Android 4.2.2 and 4.3Firebase Storage v3 在 Android 4.2.2 和 4.3 上返回“多部分正文不包含 2 或 3 个部分”
【发布时间】:2016-08-18 13:02:22
【问题描述】:

我正在构建一个 Ionic 应用程序以部署在 Android 5 和 4 上。当我尝试使用 Firebase v3 存储引用(使用 firebase.js API)在 Android 4.2.2 和 4.3 上保存 Blob 时失败:

code: "storage/unknown" 
message: "Firebase Storage: An unknown error occurred, please check the error payload for server response." 
serverResponse: "multipart body does not contain 2 or 3 parts." 
name: "FirebaseError"

这在 Android 5.0.1 和 4.4.2 设备上运行良好。

问题: 这是 Android(或包含的 webkit)版本的硬限制吗?还是我使用的 firebase.js API 不兼容?我正在尝试了解问题是否可以解决,或者是否无能为力。

我能找到的对该错误消息的唯一其他参考是:https://github.com/davideast/firebase-react-native-sample/issues/5

但鉴于这是一个离子包装应用程序,我确实可以访问 Blob 类型。

该文件是通过使用cordova-plugin-camera 扩展程序拍照创建的,并使用Camera.DestinationType.FILE_URI 将其保存到手机本地存储中

然后使用 cordova-plugin-file 扩展名将其读回 Blob,然后再保存到 Firebase 存储(特别是 Google Cloud Store 支持的存储,因为它使用的是 firebase v3)。

Blob 似乎已成功创建(尽管如果新的 Blob 构造函数不可用,它可能会回退到使用 BlobBuilder - 请参阅代码 sn-p)

相关的代码部分(来自 AngularJS 控制器)如下所示:

var makeBlob = function(data, mimeString) {
  try {
    return new Blob([data], {
      type: mimeString
    });
  } catch (err) {
    var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder;
    var bb = new BlobBuilder();
    bb.append(data);
    return bb.getBlob(mimeString);
  }
};

$scope.uploadLocalImageAsync = function(localImageFileUrl, responseKey, description) {
  var deferred = $q.defer();

  $window.resolveLocalFileSystemURL(localImageFileUrl, function fileEntrySuccess(fileEntry) {
      fileEntry.file(function fileSuccess(file) {
        var reader = new FileReader();
        reader.onloadend = function(evt) {
          try {
            var imageBlob = makeBlob(evt.target.result, 'image/jpeg');
            alert("imageBlob: " + JSON.stringify(imageBlob));

            var metadata = {
              contentType: 'image/jpeg',
              customMetadata: {
                'response': responseKey,
                'description': description
              }
            };

            // Create a root reference
            var storageRef = firebase.storage().ref();
            var fileRef = storageRef.child('images/' + responseKey + '/' + file.name);

            var uploadTask = fileRef.put(imageBlob, metadata);
            uploadTask.on('state_changed', function(snapshot) {
              // Observe state change events such as progress, pause, and resume
              // See below for more detail
              alert(JSON.stringify(snapshot));

            }, function(error) {
              // Handle unsuccessful uploads
              alert(JSON.stringify(error));
              deferred.reject("Upload failed: " + error.code + ": " + error.message)
            }, function() {
              // Handle successful uploads on complete
              // For instance, get the download URL: https://firebasestorage.googleapis.com/...
              var downloadURL = uploadTask.snapshot.downloadURL;
              deferred.resolve({
                gsPath: fileRef.toString(),
                downloadUrl: downloadURL
              });
            });
          } catch (err) {
            deferred.reject("onloadend error: " + err);
          }
        };

        try {
          reader.readAsArrayBuffer(file);
        } catch (err) {
          deferred.reject("readAsArrayBuffer error: " + err);
        }

      }, function fileFailure() {
        deferred.reject("Couldn't make File object");
      });
    },
    function fileEntryFailure() {
      deferred.reject("Couldn't find fileEntry for image");
    });

  return deferred.promise;
};

localImageFileUrl 的格式为“file:///storage/sdcard0/Android/data/com.ionicframework.myapp/cache/1471426280702.jpg”

该函数实际上返回一个承诺,该承诺稍后会在 AngularJS 控制器的另一部分解决。

启动uploadTask后失败。

同样,这适用于 Android 5.0.1、4.4.2,但在 4.3、4.2.2 上失败

我希望 Ionic 中有一些额外的设置或者我缺少的东西。但我真的不知道是什么导致了行为上的差异,也不知道我能做些什么。


我尝试过的事情

我尝试将 cordova android 平台降级到 3.5 以专门针对 android-17 (4.2.2)(使用类似于此处的 https://stackoverflow.com/a/32672214/6729807 ),但它会产生相同的错误。

(我也将不同的插件降级到适当的级别)


有关正在使用的工具版本的一些信息

离子信息:

您的系统信息:

Cordova CLI: 6.3.1
Ionic Framework Version: 1.3.1
Ionic CLI Version: 2.0.0
Ionic App Lib Version: 2.0.0-beta.20
OS:
Node Version: v4.4.7

离子平台版本android:

Installed platforms:
  android 5.2.1

/platforms/android/AndroidManifest.xml

<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="23" />

/platforms/android/project.properties(和 CordovaLib project.properties)

target=android-23

已安装的插件:

cordova-plugin-camera
cordova-plugin-compat
cordova-plugin-file
cordova-plugin-geolocation
cordova-plugin-whitelist

使用 https://www.gstatic.com/firebasejs/3.3.0/firebase.js

https://github.com/firebase/angularfire (release v2.0.1)

【问题讨论】:

    标签: javascript android angularjs ionic-framework firebase-storage


    【解决方案1】:
    The resolving key was using RNFetchBlob.polyfill.XMLHttpRequest;
    
    import RNFetchBlob from 'react-native-fetch-blob';
    const Blob = RNFetchBlob.polyfill.Blob;
    window.XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest;
    window.Blob = Blob;
    
    install package 
    - https://github.com/wkh237/react-native-fetch-blob
    and execute code
    -  https://github.com/wkh237/rn-firebase-storage-upload-sample/blob/master/index.common.js
    
    also read http://stackoverflow.com/questions/39160006/react-native-firebase-storage-upload-using-putstring-call
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-21
      相关资源
      最近更新 更多