Convert image path to blob react native

26,564

Solution 1

If you are using expo (>=26), then you can do it easily with the following lines of code.

uploadImage = async(imageUri) => {
  const response = await fetch(imageUri);
  const blob = await response.blob();
  var ref =   firebase.storage().ref().child("image.jpg");
  return ref.put(blob);
}

Reference: https://youtu.be/KkZckepfm2Q

Solution 2

Refer this link - https://github.com/dailydrip/react-native-firebase-storage/blob/master/src/App.js#L43-L69

Following block of code is working fine.

uploadImage(uri, mime = 'application/octet-stream') {
    return new Promise((resolve, reject) => {
      const uploadUri = Platform.OS === 'ios' ? uri.replace('file://', '') : uri
      let uploadBlob = null

      const imageRef = FirebaseClient.storage().ref('images').child('image_001')

      fs.readFile(uploadUri, 'base64')
        .then((data) => {
          return Blob.build(data, { type: `${mime};BASE64` })
        })
        .then((blob) => {
          uploadBlob = blob
          return imageRef.put(blob, { contentType: mime })
        })
        .then(() => {
          uploadBlob.close()
          return imageRef.getDownloadURL()
        })
        .then((url) => {
          resolve(url)
        })
        .catch((error) => {
          reject(error)
      })
    })
  }
Share:
26,564
GIISE
Author by

GIISE

I love to code. It's mostly a hobby of mine, and I hope one day when I leave school it can become my job. I am not very good at it though );

Updated on January 29, 2022

Comments

  • GIISE
    GIISE over 2 years

    Problem

    I am trying to create an app with react native and firebase. One of the features I would like for this app is the ability to upload images. I am having some trouble uploading the images to firebase storage though. I am using expo's image picker to find the path of the image that the user wants to upload, but once I have the path I don't know how to convert that to something I can upload to firebase.

    Can somebody help me convert the path of an image to something I can upload to firebase storage with react native?

    What I've tried

    I tried using:

         _pickImage = async () => {
        let result = await ImagePicker.launchImageLibraryAsync({
          MediaTypeOptions: 'Images',
          quality: 0.4,
    _uploadAsByteArray = async (pickerResultAsByteArray, progressCallback) => {
    
        try {
    
          var metadata = {
            contentType: 'image/jpeg',
          };
    
          var storageRef = firebase.storage().ref();
          var ref = storageRef.child('images/'+expoID+'/'+this.state.time)
          let uploadTask = ref.put(pickerResultAsByteArray, metadata)
    
          uploadTask.on('state_changed', function (snapshot) {
    
            progressCallback && progressCallback(snapshot.bytesTransferred / snapshot.totalBytes)
    
            var progress = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
            console.log('Upload is ' + progress + '% done');
    
          }, function (error) {
            console.log("in _uploadAsByteArray ", error)
          }, function () {
            var downloadURL = uploadTask.snapshot.downloadURL;
            console.log("_uploadAsByteArray ", uploadTask.snapshot.downloadURL)
        this.setState({imageUploaded:true})
          });
    
    
        } catch (ee) {
          console.log("when trying to load _uploadAsByteArray ", ee)
        }
      }
    
    
      convertToByteArray = (input) => {
        var binary_string = this.atob(input);
        var len = binary_string.length;
        var bytes = new Uint8Array(len);
        for (var i = 0; i < len; i++) {
          bytes[i] = binary_string.charCodeAt(i);
        }
        return bytes
      }
    
      atob = (input) => {
        const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
    
        let str = input.replace(/=+$/, '');
        let output = '';
    
        if (str.length % 4 == 1) {
          throw new Error("'atob' failed: The string to be decoded is not correctly encoded.");
        }
        for (let bc = 0, bs = 0, buffer, i = 0;
          buffer = str.charAt(i++);
    
          ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer,
            bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0
        ) {
          buffer = chars.indexOf(buffer);
        }
    
        return output;
      }
    
    
    uploadImage(bsfdata){
        this.setState({imageUploaded:false})
        this._uploadAsByteArray(this.convertToByteArray(bsfdata), (progress) => {
        this.setState({ progress:progress })
        })
      }
      base64:true,
    });
    
    
    
     /* if (!result.cancelled) {
          this.setState({ image: result.uri });
          let formData = new FormData();
            formData.append('photo', {
               uri,
               name: `photo.${fileType}`,
               type: `image/${fileType}`,
         });}*/
          this.uploadImage(result.base64);
      };
    
    }
    

    I've tried it with the commented code added, which doesn't upload anything, and I've tried it with how the code is now, which gives me the error Can currently only create a Blob from other Blobs, and the uploading progress never gets above 0%.

  • Andrew Irwin
    Andrew Irwin almost 6 years
    just FYI, for anyone who wants to upload an image to firebase storage who is not using expo (Like I'm not), you can just pass the image uri as the first param to the ref.put() function. i.e ref.put(uri)
  • Jaffer Sathick
    Jaffer Sathick over 5 years
    @K.Wu . i am getting Attempt to invoke interface method 'java.lang.String.facebook.react.bridge.readablemap.getstrin‌​g(java.lang.string) on a null object reference exception when i add "window.Blob = Blob;", if i remove this no exception but blob format is not correct . Please help
  • stevejboyer
    stevejboyer almost 5 years
    @AndrewIrwin perhaps it was possible when you wrote that comment, but now the put method requires a Blob or File. Passing the URI string will result in an error being thrown.
  • stevejboyer
    stevejboyer almost 5 years
    What is window in this case? There is no native window object in react-native...
  • Coder828
    Coder828 about 4 years
    It's missing "then" from Blob.build... .((url) => {
  • Doongsil
    Doongsil over 3 years
    Thanks! I think this is the most simple solution.
  • howard
    howard over 3 years
    Not expo compatible unfortunately
  • Ravi
    Ravi over 3 years
    It gives network error sometimes without any reason. Sometimes it works like a chram