DEV Community

Cover image for Store and Retrieve Data in Firebase Cloud Storage with React.js
Melvin Chidiebere
Melvin Chidiebere

Posted on • Updated on

Store and Retrieve Data in Firebase Cloud Storage with React.js

Introduction

Cloud computing is the use of a network of remote servers that are hosted on the internet. These remote servers are used to store, manage and process data. The use of cloud will also help companies and developers make systems more secure. Cloud systems enable you to maintain data integrity and data recovery. Developers who don’t use cloud will have less secure software and computer networks that can result in loss of key data.

Firebase

We will use Firebase a platform developed by Google for creating mobile and web applications. It was originally an independent company founded in 2011. Its first product was the Firebase Realtime Database, an API that synchronizes application data across iOS, Android, and Web devices, and stores it on Firebase's cloud. The product assists software developers in building real-time, collaborative applications. In October 2017, Firebase has launched Cloud Firestore, a real-time document database as the successor product to the original Firebase Realtime Database

React

We will use React (also known as React.js or ReactJS) a free and open-source front-end JavaScript library for building user interfaces or UI components.

Getting Started

In this tutorial we will be learning how to store and retrieve data in firebase by building a todo-list app.

Note

  • You should have Node.js installed on your computer.
  • You should have a code editor installed on your computer, I suggest VS-Code
  • You should be fairly familiar with React.js and JavaScript

Next thing is creating an empty folder in any directory on your computer preferably Desktop, with a folder name of your choice, in my case firebase-todos
Now from your code editor open the folder firebase-todos then click on terminal in the vs-code navigations and click on new terminal, before we start running the Npm CLI-commands we first have to check whether Node.js is properly installed by running node --version which will show us the version of node successfully installed.

Now let's run our command npx create-react-app . with the dot to create the app inside our firebase-todos folder. See more about creating react-app Now let's start our created app, to do that we run npm start in the terminal. Our app should start on localhost:3000 of our default browser with spinning react icon and a link to learn react.

It's time to clean up our created app so that the frontend should be what we really want, so let's delete some of the files inside the src folder that we don't need.
Let's get rid of the following files

  • App.css
  • App.test.js
  • logo.svg
  • reportWebVitals.js
  • setupTest.js

Once we delete these file our app will break because in the remaining files, we are trying to read those deleted files, so let go get rid of those lines of codes.
Inside App.js file delete the first two lines of code also delete the header tag with everything inside it then add a <h1> hello world </h1>.
So App.js will no look like this

function App() {
  return (
    <div className="App">
      <h1>hello world</h1>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

In index.js get rid of import reportWebVitals from './reportWebVitals'; and reportWebVitals(); at the bottom.

Now index.js will look like this

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';


ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById('root')
);
Enter fullscreen mode Exit fullscreen mode

When you save, our app would be up again showing just hello world in the browser like below.
hello-world image

Inside the src folder let's create another folder called Components and inside Components we will create three other files called Firebase.js, Header.js and Todos.js.

components-img

In Firebase.js we will be make communications to firebase, in Header.js we will be branding our project and also will be inputing our different todos and from Todos.js we will be displaying our todos.

The next thing is setting up firebase firestore in Firebase.js file so let's go to Firebase you need to create an account or sign in if you already have one, then click on the add project card, name your project and click continue, turn off the google analytics and click continue to create your project.
create-project-img

Next click on the cloud firestore to create firestore database(where we would store our data), click on create database choose either the test or production mode and click next, choose your closest cloud firestore location and click enable, yes we created our firestore database.
create-firestore-database

After creating our firestore database the next thing is to create our app, ie IOS, MOBILE OR WEB APP. So click on the setting icon beside the project overview from the dropdown click project setting, choose web application, choose a name for the app and click register app.
create-app

We are almost done with setting up firebase storage, right now we can't store our data in our firestore database because of the store rules, so in the firestore console navigate to rules and allow read, write, create like below

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read;
      allow create;
      allow request;
      allow update: if false;
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

It's time to go back to our code editor but before we proceed we need to copy our firestore database configurations, so click on the setting icon, scroll down and copy everything inside the script tag.

Back in your code editor open your terminal and run npm install firebase to install firebase then inside the Firebase.js file import firebase and paste the configuration you copied from firebase console, then export it by adding the last line of code like below so you would be able to import and use it in another file when you need to. Your Firebase.js file should look below

import firebase from "firebase"

// Your web app's Firebase configuration
var firebaseConfig = {
    apiKey: "AIzaSyCceIp****Jp3zbobYqcV_EefHQ0U23J_o",
    authDomain: "todos-31072.firebaseapp.com",
    projectId: "todos-31072",
    storageBucket: "todos-31072.appspot.com",
    messagingSenderId: "494703082670",
    appId: "1:494703082670:web:711****7f533807ebe813f"
  };
  // Initialize Firebase
  firebase.initializeApp(firebaseConfig);
// export Firebase so it can be used elsewhere 
 const FireBase = firebase.initializeApp(firebaseConfig);
export default Firebase;
Enter fullscreen mode Exit fullscreen mode

Next thing, we go into our Header.js file and create our frontend layouts, ie the project title and input element to type in our todos and a submit button.

So let's write these lines on code in our Header.js

import React, { useState } from "react";

function Header() {
  const [input, setInput] = useState("");

  const handleSubmit = (e) => {
    e.preventDefault();
    alert("Hello " + input);
    setInput("");
  };

  return (
    <>
      <center>
        <form onSubmit={handleSubmit}>
          <h1 className="title" style={{ color: "red" }}>
            My Todos
          </h1>
          <div className="input">
            <input
              type="text"
              required
              placeholder="What do you need to do today?"
              value={input}
              onChange={(e) => setInput(e.target.value)}
            />
            <button type="submit">Submit</button>
          </div>
        </form>
      </center>
    </>
  );
}

export default Header;
Enter fullscreen mode Exit fullscreen mode

Now import the Header like so import Header from "./Components/Header"; inside the App.js file, get rid of h1 and it's content then render the <Header />.
If you did everything correctly in your browser, it should now look like below

myTodos

Everything is working like we wanted, so let's save our input in firestore once we click the submit button instead of alerting Hello (whatever our input is). We will save and get todos from firebase inside the App.js file and pass the functions as props to each component that needs it. Inside App.js let's get our firebase configurations from Firebase.js like so import FireBase from "./Components/Firebase";

The next is to save our input data to firebase collection, so App.js will now look like below

import React from "react";
import Header from "./Components/Header";
import { v4 as uuid } from "uuid/";
import FireBase from "./Components/Firebase";

function App() {
  const saveTodo = (input) => {
    const saveToFirebase = FireBase.firestore();
    saveToFirebase.collection("todos").add({
      id: uuid(),
      item: input
    });
  };
  return (
    <div className="App">
      <Header saveTodo={saveTodo} />
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Above we created saveTodo function and pass input as it's parameter which will actually come from the input in our Header.js file, then called firestore function upon the Firebase configuration we imported from Firebase.js, then set our collection id and finally added our object the has an id and item which takes the input parameter.
Also we passed down our saveTodo function to the header component, so inside the Header.js we will destructure and pull out the saveTodo function and call it inside the handleSubmit function and pass our actual input as the input parameter it requires. So Header.js will now look like below

import React, { useState } from "react";

function Header({ saveTodo }) {
  const [input, setInput] = useState("");

  const handleSubmit = (e) => {
    e.preventDefault();
    saveTodo(input);
    setInput("");
  };

  return (
    <>
      <center>
        <form onSubmit={handleSubmit}>
          <h1 className="title">My Todos</h1>
          <div className="input">
            <input
              type="text"
              required
              placeholder="What do you need to do today?"
              value={input}
              onChange={(e) => setInput(e.target.value)}
            />
            <button type="submit">Submit</button>
          </div>
        </form>
      </center>
    </>
  );
}

export default Header;

Enter fullscreen mode Exit fullscreen mode

Now whatever you type in as your todo and hit submit, it will be saved in firebase under todos collection.
Let's get our todos from firebase, let head back to App.js and create a getTodos function. First we need to create todos state and set it equals to an empty array so in our getTodos function we would update the todos and set it equals to the data we would get from firebase. we would now pass down the state todos to any component that would be needing it, in our case Todos.js. App.js will now look like below

import React, { useState } from "react";
import Header from "./Components/Header";
import { v4 as uuid } from "uuid/";
import FireBase from "./Components/Firebase";

function App() {
  const [todos, setTodos] = useState([]);

  const saveTodo = (input) => {
    const saveToFirebase = FireBase.firestore();
    saveToFirebase.collection("todos").add({
      id: uuid(),
      item: input,
    });
  };
  const getTodos = () => {
    const getFromFirebase = FireBase.firestore().collection("todos");
    getFromFirebase.onSnapshot((querySnapShot) => {
      const saveFirebaseTodos = [];
      querySnapShot.forEach((doc) => {
        saveFirebaseTodos.push(doc.data());
      });
      setTodos(saveFirebaseTodos);
    });
  };

  return (
    <div className="App">
      <Header saveTodo={saveTodo} getTodos={getTodos} />
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

In the getTodos()we targeted our collection "todos", then used firestore's onSnapShot() to listen to our document and creates a document snapshot immediately with the current contents, each time the contents change, another call updates the document snapshot, then created an empty array and pushed the data onSnapShot() returned and finally set our state todos equals to the array.

We will want to call getTodos() each time we add a new todo, so we will pass the getTodo() to our Header.js component, then pull it out in Header.js and call it immediately after saveTodo() in handleSubmit().

Next, we will call the getTodos() once our page loads to have access to previously saved todos and set them equals to our state todos, we will do that with the react useEffect hook.
Finally in App.js, import and render our Todos.js Component and pass down the state todos as the Component props. App.js would finally look like below

import React, { useState, useEffect } from "react";
import Header from "./Components/Header";
import { v4 as uuid } from "uuid/";
import FireBase from "./Components/Firebase";
import Todos from "./Components/Todos";

function App() {
  const [todos, setTodos] = useState([]);

  useEffect(() => {
    getTodos();
  }, []);

  const saveTodo = (input) => {
    const saveToFirebase = FireBase.firestore();
    saveToFirebase.collection("todos").add({
      id: uuid(),
      item: input,
    });
  };
  const getTodos = () => {
    const getFromFirebase = FireBase.firestore().collection("todos");
    getFromFirebase.onSnapshot((querySnapShot) => {
      const saveFirebaseTodos = [];
      querySnapShot.forEach((doc) => {
        saveFirebaseTodos.push(doc.data());
      });
      setTodos(saveFirebaseTodos);
    });
  };

  return (
    <div className="App">
      <Header saveTodo={saveTodo} getTodos={getTodos} />
      <Todos todos={todos} />
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Next, we head straight to Todos.js and pull out the state todos we passed down to it from App.js, then we map through the todos and display each todo in our frontend. So Todos.js will look like below

import React from "react";

function Todos({ todos }) {
  return (
    <div>
      <ul>
        {todos.map((todo) => (
          <li key={todo.id}>
            {todo.item}
          </li>
        ))}
      </ul>
    </div>
  );
}

export default Todos;
Enter fullscreen mode Exit fullscreen mode

By now if you did everything correctly you would have your todos displayed in your frontend. Below is my end result
final result
Here is the github repository for the code and the styles. Congratulation you have successfully saved and retrieved data in firebase cloud storage.

Conclusion

In this Project we built a Todo App using React.js and Firebase. With React we created a client that sends data to firebase firestore to store and also a client that consumes the stored data, with Firebase firestore we were able to save the data client provided and give back the said data to the client. For more resources on these tools, visit the documentation of React and Firebase.

Discussion (1)

Collapse
neoprint3d profile image
Drew

can u sumbit a github repository with the final product?