Integrate Firebase with React & Redux | Building a TODO List

Today we will learn how to integrate React, Redux and Firebase Database by building a simple Todo Application. At some point in our development journey, we all need a strong backend solution for tasks like Realtime Chat, storing User Data, Monitoring Apps and many more scenarios. 

Along with using React, we will also use the Redux library to manage the state of our TODO app. Actually Redux is not necessary for a simple app like our TODO List App, but we are going to use redux for this example so that it will help you understand the steps that are needed in order to add Redux to any React application.

What is a Crud Application?

CRUD is an acronym for the four basic types of SQL commands: Create , Read , Update , Delete. Most applications have some kind of CRUD functionality, and we can assume that every programmer had to deal with CRUD at some point. Our TODO App is based on this concept.

What is React?

So What is React.js? React is an open-source JavaScript library which is used for building user interfaces (Single Page Applications). React handles the view layer for web app and mobile applications. It also allows us to create reusable UI components.

What is Firebase?

Firebase is a cloud-based service that provides most of the server-side features for our react applications so that we don’t have to manually manage the infrastructure like databases, servers and server-side stuff by yourself.

Setup

Before we start building our app, we’ve to make sure that we have latest versions of Node, NPM, and the Create-React-App CLI installed. If you don’t have node.js installed, go to nodejs.org and install the latest version.

The Create-React-App CLI is now on version 3.2.0. You can update it by installing it using npm, or you can simply use the npx command that will use the CLI without installing it on your pc.

Now, Create a new React App Project Directory using the create-react-app CLI as shown below:

$ create-react-app firebase-react-todo
$ cd firebase-react-todo

The command above will create a new folder on your system named firebase-react-todo that will contain code for our react application. You can run the start script using npm or yarn to launch the app on the browser at localhost:3000.

Next, go to the src folder and delete everything from inside it, except the registerServiceWorker.js file. Once you are done deleting all the files from the src folder, we will work on integrating Redux into our Cool App.

Adding Redux to our App

According to their documentation:

Redux is a predictable state container for JavaScript apps.

In easy words, Redux is a state management library built for maintaining the data of JavaScript applications. The important thing to notice is that redux will keep all the data of our application in a single place named Store. When any component of our app requires some data, Redux will take it from the store and give it to the component.

First, we need to install the redux and react-redux to help connect React with Redux into our app, and the redux-thunk library to act as a middleware and handle asynchronous actions in Redux. This is important since we are using Firebase as the database, so chances are that we will need to perform some asynchronous request to fetch the data from firebase.

yarn add redux react-redux redux-thunk

Once everything is installed, now we can start working on Redux side of our app by creating the Reducers.

Reducers

Redux uses Reducers to change the state of the app. They know what to do with an action and its information. Now create a new folder named reducers with a file named data.js inside the src folder. The reducer function has two arguments, one is the initial state and second is the action.

Inside the data.js file, write the following:

import {FETCH_TODOS} from '../actions/types';
export default (state = {}, action) => {
  switch(action.type) {
    case FETCH_TODOS:
      return action.payload;
    default:
      return state;
  };
};

The reducer function above checks if the action triggered by the component is of type FETCH_TODOS. If it is, then it will update the state of our app with the list of todos that will be fetched by the action.

Rather than importing multiple reducer functions, we can simply combine them into one reducer by creating a new file named index.js in the same folder and writing the following code:

import {combineReducers} from 'redux';
import data from './data';
export default combineReducers({
  data
});

The redux library contains a function named combineReducers that can take multiple reducers and combine them into one reducer.

Now, we will create the Redux store where all the app data will be kept. Inside the src folder, create a file named index.js.

The state of any React app is said to flow in only one direction, from the top most file to bottom. The index.js file is the top most file of our app because this is where the App component will be rendered. The App component can further have other components inside it. So we need to create the store in the index.js file as shown below:

import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from 'react-redux';
import {createStore, applyMiddleware} from 'redux';
import reduxThunk from 'redux-thunk';
import reducers from './reducers';
import App from './App';
import * as serviceWorker from './serviceWorker';const store = createStore(reducers, {}, 

applyMiddleware(reduxThunk));ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("root")
);
serviceWorker.register();

Apart from creating our store with reducers and reduxThunk as the middleware, we are also rendering the App component using the ReactDOM. The App component is wrapped in the Provider component of react-redux library. The Provider also takes the store prop and declares it as the entire application’s store.

Redux takes away the pain from data management. With redux, we’re able to separate the Model logic from the View in a scalable way.

Adding Firebase to our React TODO App

Before we start, we need to have a Google Account. With your google account visit https://firebase.google.com/ and log in with your credentials. You can go to the Firebase console where Firebase will ask you to Create a Project with your country. You can give it the same as your React App, as it will keep things simple. Firebase UI is very friendly and guides you through every step so don’t need to worry about anything once you entered in the console.

First, Let’s start configuring the Firebase Realtime Database. Click on the Database tab, Make sure that you are selecting the Realtime Database, and then click on the Create database button shown below:

Select the “Start in test mode” option and click on the enable button.

With this, we have to set up the Firebase project and created a Realtime Database for our app. But we still need to connect the Firebase project with our React TODO App. To do so, we need to install the Firebase library inside our React app using npm.

$ npm install firebase --save

In the Firebase project’s homepage, you will notice three circular icons. The first two will contain code that will help you connect the firebase project to an iOS and Android app respectively, while the third one will have code that will help you connect the project to a web app (which is what we want). Click on it and copy the apiKeyauthDomaindatabaseURLprojectIdstorageBucket, and messagingSenderId values. These values are unique for each user’s each project and hence I am sharing the screenshot for this part.

Inside the React project directory, go to the src folder and create a new file named firebase.js. Inside this folder, write the values that we copied from the Firebase here as shown below:

import * as firebase from 'firebase';
const config = {
  apiKey: "Enter your apiKey here",
  authDomain: "Enter your authDomain here",
  databaseURL: "Enter your databaseURL here",
  projectId: "Enter your projectId here",
  storageBucket: "Enter your storageBucket here",
  messagingSenderId: "Enter your messagingSenderId here"
}
firebase.initializeApp(config);
const databaseRef = firebase.database().ref();
export const todosRef = databaseRef.child("todos")

Similar to Redux, the Firebase database has something called the Firebase Ref. This is a reference to the data that we want to access from the Firebase database. The Firebase Ref emits a series of value events, which are Firebase’s way of telling us that it has received some new data from the application.

So we have connected our React TODO app with the Firebase Project, Now we are going to use the Firebase’s Realtime database to store the list of todos. We will add a listener to the list of todos so that whenever the list changes, the app will know about the change and fetch the new data from Firebase and display it. To do this, we have one last thing to take care of on the Redux side of things, and that is called Actions.

Setting Up Actions

Even though our React and Firebase are connected, we still need Firebase to work with Redux, because Redux is handling the local data of our App.

For that we are going to take the Firebase Ref that we have named as todosRef and stick it into an action creator. So whenever the Firebase Ref emits a value event, the Firebase Ref will be turned into an action and sent to the reducers.

Inside the src folder, create a new folder called actions. Inside this folder create a new file named index.js. This file will contain 3 actions — one to add a todo to the list, another to remove it from the list, and the third one to listen for any changes in the list and according fetch the changes to the app.

import {todosRef} from '../firebase'
const FETCH_TODOS = 'FETCH_TODOS';export const addToDo = newToDo => async dispatch => {
todosRef.push().set(newToDo);
};export const completeToDo = completeToDo => async dispatch => {
todosRef.child(completeToDo).remove();
};export const fetchToDos = () => async dispatch => {
todosRef.on("value", snapshot => {
dispatch({
type: FETCH_TODOS,
payload: snapshot.val()
});
});
};

Final Step

We are almost done with our app. All that is left to do is build the UI side of things. For that, we will create a new folder named components inside the src folder. Inside the components folder, create a file named ListItem.js. This file will render each individual ToDo item. Each item will contain a button which when clicked will deem the ToDo as completed and remove it from the list. This is achieved with the help of the completeToDo action that we had created in the actions section of this post. The actions are connected to the component with the help of the connect method of react-redux library.

import React, {Component} from 'react';
import {connect} from 'react-redux';
import {completeTodo} from '../actions';
class ListItem extends Component {
  handleComplete = completeTodo => {
    const {completeTodo} = this.props;
    completeTodo(completeTodo);
  };
  render() {
    const{todoId, todo} = this.props;
    return (
      <div key="toDoName">
        <h4>
          {todo.title}
          <span onClick={() => this.handleComplete(todoId
            <i>Complete</i>
          </span>
        </h4>
      </div>
    );
  }
}export default connect(null, {completeTodo})(ListItem);

Next, we need to create another file named TodoList.js. This file will contain a form that we will use to create a new Todo. It will appear on the screen when we click on the Add button. This component will trigger the addTodo action when submitting form. And it will listen for changes in database using fetchTodos action. The connect method in this component will take in the mapStateToProp function, which we will use to access the data from the store.

Finally, We need to render these components into the src folder’s App.js file as shown below:

import React, {Component} from 'react';
import TodoList from './components/TodoList';
class App extends Component {
  render() {
    return (
      <div>
        <List/>
      </div>
    );
  }
}
export default App;

And Yay! Our React Todo List app is complete. We’ve succesfully connected our React App to Firebase.

Best resources to learn React.js and firebase

Leave a Reply

Your email address will not be published. Required fields are marked *

Trending