Uploading Images to Firebase Storage in React Native with Expo Workflow.
Tags: expo, reactnative, firebase, javascript
Published: 2022-07-22 11:35:26

There are many ways of uploading local images and videos to Firebase Storage in React Native and we'll be seeing Blob Implementation through a custom `XMLHTTPRequest`.

## 1. Lets start with creating a Firebase Project.

- Visit [Firebase Console](https://console.firebase.google.com/u/5/) and Click on Create a Project.

- Provide You App Name and Continue.
![Firebase SS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h31kmafjivyi8aa25bzb.png)
- Once the Project has been created, create a Web App.
![Firebase SS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zo83848ba6xe0jlwk5hh.png)
- Provide the name of the web app and click on Continue to Console.
 

## 2. Creating a React Native App in Expo

- Create a react native app in expo by `expo init ProjectName`

- We will be using [Expo-Image-Picker](https://docs.expo.dev/versions/latest/sdk/imagepicker/) for picking up the images from our device. Lets install expo image picker in our project `yarn add expo-image-picker`

- Lets add Firebase to the project using `yarn add firebase@9.6.11`

- Now let's add the configuration details for the firebase project that we created.
Create a file named `firebase.js` and get your firebase project config details from the app setting.

![App setting SS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wdh7ql1gedjsr4euux1r.png)

- In the file `firebase.js`, we will save the firebase config details and initialize the app

```
import firebase from 'firebase/compat/app'
import 'firebase/compat/storage'
import { initializeApp } from "firebase/app";

export const firebaseConfig = {
  apiKey: "KEY",
  authDomain: "authDomain",
  projectId: "ProjectID",
  storageBucket: "storageBucketId",
  messagingSenderId: "sendrId",
  appId: "appId"
};

if (!firebase.apps.length) {
    firebase.initializeApp(firebaseConfig)
}

const app = initializeApp(firebaseConfig);

export {app, firebase}
```

- Let's create an async function for picking image using expo image picker

```
const [image, setImage] = useState(null)
const [uploading, setUploading] = useState(false)
const pickImage = async () => {
    let result = await ImagePicker.launchImageLibraryAsync({
      mediaTypes: ImagePicker.MediaTypeOptions.All, // We can 
             specify whether we need only Images or Videos
      allowsEditing: true,
      aspect: [4, 3],
      quality: 1,   // 0 means compress for small size, 1 means 
                       compress for maximum quality
    });

    console.log(result);

    if (!result.cancelled) {
      setImage(result.uri);
    }
  };
```

- Now let's implement the blob functionality for pushing the image to firebase storage

```
const uploadImage = async () => {
    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', image, true);
      xhr.send(null);
    })
    const ref = firebase.storage().ref().child(`Pictures/Image1`)
    const snapshot = ref.put(blob)
    snapshot.on(firebase.storage.TaskEvent.STATE_CHANGED,
      ()=>{
        setUploading(true)
      },
      (error) => {
        setUploading(false)
        console.log(error)
        blob.close()
        return 
      },
      () => {
        snapshot.snapshot.ref.getDownloadURL().then((url) => {
          setUploading(false)
          console.log("Download URL: ", url)
          setImage(url)
          blob.close()
          return url
        })
      }
      )
  }
```




- Now lets create a simple UI with 2 Buttons and call `pickImage` and `uploadImage` from `onPress`.

```
<View style={styles.container}>
      {image && <Image source={{uri: image}} style={{width: 170 , height: 200}}/>}
      <Button title='Select Image' onPress={pickImage} />
      {!uploading ? <Button title='Upload Image' onPress={uploadImage} />: <ActivityIndicator size={'small'} color='black' />}
    </View>
```
I have added an Activity Indicator which will tell the user that the image is being uploaded.

![App SS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z89yue5k7mbg8q3jgrru.jpeg)

- When the user clicks on select Image button, native image library will open and once you pick the Image, the selected Image will be displayed


![Image Picked SS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ljgdrc7kyfh8z5559bpu.jpeg)

- When the user clicks on Upload Image button, the activity indicator will appear and the image will be uploaded to firebase Storage.

![Upload SS](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/msqqs5luzk2xrxxuzogb.jpeg)

The full code can be found [here](https://github.com/adii9/Image-Upload-to-Firebase).

Also, if you enjoyed this content and would like to stay updated on future posts, feel free to connect with me on [LinkedIn](https://www.linkedin.com/in/aditya-mathur-52322b16a/) or [X](https://twitter.com/adii_mathur) or check out my [Github ](https://github.com/adii9)profile. I'll be sharing more tips and tricks on Django and other technologies, so don't miss out!

If you find my content valuable and would like to support me, you can also [buy me a coffee](https://www.buymeacoffee.com/aditya360l). Your support helps me continue creating helpful and insightful content. Thank you!