Firebase Storage v3 returns "multipart body does not contain 2 or 3 parts" on Android 4.2.2 and 4.3

I am creating an Ionic application for deployment on Android 5 and 4. When I try to use firebase v3 storage ref (using firebase.js API) to save Blob on Android 4.2.2 and 4.3, this is not with:

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"

This works great on Android 5.0.1 and 4.4.2 devices.

Question: Is this a severe limitation of the versions of Android (or the website included)? Or some incompatibility in the firebase.js API I'm using? I am trying to understand if the problem can be fixed or if there is nothing to be done.

The only other mention of this error message that I could find was here: https://github.com/davideast/firebase-react-native-sample/issues/5

But, seeing that this is an ion-shell application, I have access to the Blob type.

The file is created by shooting using the extension cordova-plugin-camera, saving it to the local phone storage with Camera.DestinationType.FILE_URI

It is then read back into Blob using the file extension plugin before saving it to the Firebase store (in particular, the store with the Google Cloud Store, because it uses firebase v3).

It seems that Blob was created successfully (although it may revert to using BlobBuilder if a new Blob constructor is not available - see code snippet)

The corresponding section of code (from within the AngularJS controller) looks like this:

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;
};
Run code

localImageFileUrl has the form "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 - -, . , , - .


:

android- cordova 3.5, Android-17 (4.2.2) ( - qaru.site/questions/333046/...), .

( )


:

:

:

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( project.properties CordovaLib)

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)

+4
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
+1

Source: https://habr.com/ru/post/1651673/


All Articles