Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Uploading Image to Firebase in React Native

I have two image paths in my component state

enter image description here

I try to upload one of the images inside of a function but get an error:

Firebase Storage: Invalid argument in 'put' at index 0: Expected Blob or file

and my function

submitImages = () => {

    // Upload images to Firebase storage
    let user = firebaseAuth.currentUser;
    let imagesRef = storageRef.child('productImages/' + user.uid);
    imagesRef.put(this.state.imageFront).then(snapshot => {
        console.log('Uploaded ' + this.state.imageFront);
    });
}

What should I be doing instead to get these images up to Firebase. Thanks!

like image 900
maxwellgover Avatar asked Feb 14 '17 01:02

maxwellgover


2 Answers

What the error says is that you need to use a blob. You can use react-native-fetch-blob: https://github.com/wkh237/react-native-fetch-blob

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

like image 140
Franzé Jr. Avatar answered Oct 06 '22 20:10

Franzé Jr.


I am posting my code since this was a bit frustrating for me:

To upload images to firebase.storage you need to upload the images as Blobs. If you don't know what Blobs are, don't worry: BLOB stands for Binary Large OBject.

Step 1.

npm install --save react-native-fetch-blob

Step 2.

// copy and paste this code where you will handle the file upload

import RNFetchBlob from 'react-native-fetch-blob'

const Blob = RNFetchBlob.polyfill.Blob;
const fs = RNFetchBlob.fs;
window.XMLHttpRequest = RNFetchBlob.polyfill.XMLHttpRequest;
window.Blob = Blob;

Step 3.

// The uploadImage function that you are going to use:

function uploadImage(uri, mime = 'image/jpeg', name) {
  
  return new Promise((resolve, reject) => {
    let imgUri = uri; let uploadBlob = null;
    const uploadUri = Platform.OS === 'ios' ? imgUri.replace('file://', '') : imgUri;
    const { currentUser } = firebase.auth();
    const imageRef = firebase.storage().ref(`/jobs/${currentUser.uid}`)

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

So how do you call this function? Pass the URI of the image as the first argument. In my case img1, img2, img3 where variables that pointed to the URIs of the images, that I wanted to upload which were on my phone. They looked something like '/Phone/Pics/imageToUpload.jpeg', etc.

As the second argument you can pass 'image/jpeg' and the last argument is the name that you want to give the image. Chose the name that you like.

But what if I have several images and want to upload them and want to handle the upload correctly. What if one upload succeeds and the other does not?

Do this then:

let imgPromises = [];
imgPromises.push(uploadImage(img1, 'image/jpeg', 'imageOne'));
imgPromises.push(uploadImage(img2, 'image/jpeg', 'imageTwo'));
imgPromises.push(uploadImage(img3, 'image/jpeg', 'imageOne'));

Promise.all(imgPromises).then(urls => {
  // ALL IMAGES SUCCEEDED and you will get an array of URIS that you can save to your database for later use!
}).catch(error => {
  // One OR many images failed the upload. Give feedback to someone.
})
like image 39
Walter Monecke Avatar answered Oct 06 '22 22:10

Walter Monecke