Introduction to Firebase Storage #1: Uploading Files
Tags: firebase, react, storage, beginners
Published: 2020-12-29 02:49:57

---
title: Introduction to Firebase Storage #1: Uploading Files
published: true
date: 2020-11-21 04:21:19 UTC
tags: Firebase,React,storage,beginners
canonical_url: https://lo-victoria.com/introduction-to-firebase-storage-uploading-files
---

Some apps allow users to upload images and files, read them, delete them and even download them whenever users want. Such functionality can be useful for social media platforms, blogging platforms or storage services. Firebase Cloud Storage offers a solution to store user-generated content easily. 

Hello fellow devs, in this article, we'll be discussing Firebase Cloud Storage and how we can implement it to upload, retrieve and store user files securely.

## What is Firebase Cloud Storage?
Firebase Cloud Storage is a service that developers can use to store and download files generated directly by clients. No server-side code is needed. 

It uses Google Cloud Storage buckets to store the files, allowing accessibility from both Google Cloud and Firebase. These buckets are formed within a hierarchical structure. For example:

![structure](https://cloud.google.com/billing/docs/images/resource-hierarchy-overview.png)

What I really like about Firebase Cloud Storage is how seamless it integrates with Firebase Authentication so you can organize uploaded files based on each user and apply access controls if needed. 

Also, it scales automatically so there's no worry about moving to another provider when stored data gets too large.

Now that we know what Firebase Storage can do, let's try using it in our project. For this tutorial, I'm making a simple photo album app that allows users to upload, view and delete images.

## Step 1: Create a new Firebase Project
Head over to firebase.google.com and create a new project.

![1.PNG](https://cdn.hashnode.com/res/hashnode/image/upload/v1600303907780/KdWPwlQLu.png)

On the dashboard, click on the Web icon to initialize Firebase for Web Apps.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1600304103899/Dbm6A9Qfk.png)

Follow the steps by Firebase and you'll reach a page that shows your config variables (see image below). This is important so copy and save it somewhere. We will use it soon.

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1600304118375/NriRpcYnd.png)

Next, head over to the **Storage** tab and click on the **'Get Started'** button.

![2.PNG](https://cdn.hashnode.com/res/hashnode/image/upload/v1600304375295/1Pqiesw-C.png)

You'll see a pop-up window that asks if you are okay with some settings. Replace the `request.auth !=null` to `true`. This ensures we are allowed to upload files to Firebase without needing authentication for the simplicity of this tutorial.

Click **'Next'** to proceed.

![3.PNG](https://cdn.hashnode.com/res/hashnode/image/upload/v1600391465512/PwN8MPGBU.png)

And there you go! Firebase Cloud Storage is now enabled. Let's integrate it into our app.

## Step 2: Create a React App
For this example, I'm using a react project template. You can use whatever front-end framework you like.

To create a React project, simply run:
```
npx create-react-app <app-name>
```
Once your project is created, run:
```
npm install firebase
```
This is a package that contains the necessary tools and infrastructure we need to set up Firebase in our app.

## Step 3: config.js
Create a file called `config.js` to store our Firebase config variables that we copied earlier.

Our `config.js` will look like:
```
import firebase from "firebase/app";
import "firebase/storage";

const app = firebase.initializeApp({
  apiKey: process.env.REACT_APP_API_KEY,
  authDomain: process.env.REACT_APP_AUTH_DOMAIN,
  databaseURL: process.env.REACT_APP_DATABASE_URL,
  projectId: process.env.REACT_APP_PROJECT_ID,
  storageBucket: process.env.REACT_APP_STORAGE_BUCKET,
  messagingSenderId: process.env.REACT_APP_MESSAGING_SENDER_ID,
});

// Get a reference to the storage service, export it for use
export const storage = firebase.storage(); 

export default app;
```
Note that I'm storing the actual config values in my `.env` file and accessing them as `process.env.VARIABLE_NAME`.

> If you are new with environment variables, I found this nice [article](https://dev.to/deammer/loading-environment-variables-in-js-apps-1p7p) explaining how to use it.

## Step 4: Uploading Files to Storage
In `App.js`, we can import our storage reference that we exported from our `config.js` file.
```
import {storage} from "./config";
```
In order to upload files, we need to have an input field for the user. We can create an input element like so:

```
<input type="file" accept="image/x-png,image/jpeg" />
```
By specifying the `type` to file, the input field will be a file picker. 

For this example, we only accept files that are `.png` or `.jpeg`. We can specify this requirement in the `accept` attribute.

Now let's add a button that will upload our image to Firebase when clicked.
```
 <button>Upload to Firebase</button>
```
At this point, the UI should look something simple like:

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1600306366223/ctBtN0K2B.png)

### 1. Create Image state
To track whether our user has supplied a file in the input, we should have an `image` state. First, import the `useState` hook.

```
import React, { useState } from "react";
```
And initialize the state to null:
```
const [image, setImage] = useState(null);
```

### 2. onImageChange
Next, let's create an `onImageChange` function which will update the `image` state every time the user supplied a new file to the input field.

```
const onImageChange = (e) => {
    const reader = new FileReader();
    let file = e.target.files[0]; // get the supplied file
    // if there is a file, set image to that file
    if (file) {
      reader.onload = () => {
        if (reader.readyState === 2) {
          console.log(file);
          setImage(file);
        }
      };
      reader.readAsDataURL(e.target.files[0]);
    // if there is no file, set image back to null
    } else {
      setImage(null);
    }
  };
```
Then, we will pass this function into the `onChange` handler of our input element.
```
<input type="file" accept="image/x-png,image/jpeg" onChange={(e) => {onImageChange(e); }}/>
```
### 3. uploadToFirebase
Now let's create an `uploadToFirebase` function for our button so that the image will be uploaded to Firebase when the user clicks the button.

This is how we can implement the function:
1. Check if the `image` state is null. If it is, ask the user to supply a file first. 
2. If `image` is a file, we'll create a root reference to our storage.
3. Then we create a child reference to store our file. We can name that reference by the image's `name` property.
4. Finally, use `put(image)` to store our file in the reference.
5. Then have a callback function to let the user know that the file has been uploaded to Firebase successfully.

Here's the implementation in code:
```
  const uploadToFirebase = () => {
    //1.
    if (image) {
      //2.
      const storageRef = storage.ref();
      //3.
      const imageRef = storageRef.child(image.name);
      //4.
      imageRef.put(image)
     //5.
     .then(() => {
        alert("Image uploaded successfully to Firebase.");
    });
    } else {
      alert("Please upload an image first.");
    }
  };

```
### That should do it!
Let's check if it works.

![gif.gif](https://cdn.hashnode.com/res/hashnode/image/upload/v1600310168127/Fxc-kfLzb.gif)

Yay it does! The uploaded image is in Firebase Storage.

## Conclusion
With Firebase Cloud Storage, there are many things you can do to handle, organize and store user's data and files. Stay tuned for the next article on how to retrieve, display and delete files from Firebase Storage.

Thanks for reading and I hope it was helpful in any way. Feel free to ask any questions in the comments below and refer to the Firebase [documentation](https://firebase.google.com/docs/storage) to read more about it yourself. Take care and cheers!