Creating a React + Firebase Web App

Sonali Gupta
8 min readMay 14, 2021

This is a beginner-friendly blog explaining how to create a simple to do app and perform CRUD operations using React and Firebase.

Prerequisites: React.Js

What is Firebase?

It is a platform developed by Google for creating mobile and web applications. Firebase provides an easy way to create full-stack applications. Firebase provides the Firestore for storing data in its NoSQL database and uses Firebase Authentication for providing authentication to user through account creation or simply signing in using google, github and other platforms.

Let's get started now!!

Step 1: Creating Firebase Project

  • First, go to https://firebase.google.com/
  • Click on the Console button at the top.
  • Click on create project options.
  • Add a project name and click on continue. Then, turn off Google Analytics for now as we are only focusing on building the app but you can keep it on if you want to.
  • Then click create project button after turning off Analytics. Click on the Continue button.
  • Click on the Web option on the screen to create a web app as shown below:
Click on the Web icon on this screen to create a web app
  • Register the app and write a nickname for it.
  • Then you will see Firebase SDK. These are firebase configurations that are required to set up Firebase in your react project. Copy it for now and click on the console to continue.
  • In the sidebar, go to Firestore to set up the database for your app.
  • Click on Create Database button on the screen.
  • After that, you will see Firestore rules. These are used to allow or deny access to data in your Firestore database. There are two options — Production mode, Test mode.
Firestore rules

In test mode, data can be accessed by anyone. In production mode, data is private and can be accessed only according to rules written by you.

  • Select Production mode and click on next.
  • Now, Cloud Firestore location will be asked. Select any location and click on Enable.
Cloud Firestore location
  • Now, you will see the database as shown below:

The database here is a NoSQL database so data is not stored in the form of relations. Here, data is stored in documents that contain fields mapping to values. These documents are stored in collections which are containers for your documents that you can use to organize data and build queries. Documents can be of any type — strings, numbers, or objects. We can also create subcollections within documents and build a hierarchical data structure that scales as your database grows.

  • To provide authentication so that each user can have their own account and create their own set of tasks we are going to use Firebase Authentication.
  • In the sidebar, go to Authentication and click on get started.
  • We are going to use Google Authentication for this app. So go on and enable Google authentication from the list and specify a support e-mail address and save it.

Step 2: Create the React app (CRA)

  • To create React app install create-react-app. Create-react-app provides an easy way to create react applications and installs React, ReactDOM, Eslint, and other requirements by itself. Use command npx create-react-app todo-app to install CRA and create the app.
  • Now, our goal is to create a to do app looking something like this-
Sign In Page
To do Page after signing in

There should be a Sign-in option and after signing in the page should show a sign out option, an input field to add tasks and added tasks with their progress status as well as buttons to delete the task and complete the task.

  • The basic react app with no back-end yet and no authentication functionality included yet will have the following source code. You can write your own as well, this is just for reference.
  1. index.js

2. app.js

Step 3: Install Firebase

  • Open terminal and install Firebase and React Firebase Hooks in project directory. React Firebase Hooks are for integration of React hooks with Firebase. It makes the implementation very easy.
npm i firebase react-firebase-hooks
  • Then install Firebase Tools which is Firebase CLI.
npm i -g firebase-tools
  • Next login to your Firebase account from your CLI
firebase login
  • Now, initialize your Firebase project and select Firestore and Hosting as features. After that setup your project as mentioned below —
firebase init
Firebase project initialize
Firebase project setup
  • Lastly, create a firebase_config.js file in src folder or if you don’t have src folder then create the file where other main files are present. Add the Firebase SDK configurations that you copied earlier. After that import firebase and call both firestore and auth as shown below. Then export both to be used later.

Step 4: Adding User Authentication to app

  • In the index.js file import the following —
import firebase from “firebase/app”; 
import { useAuthState } from “react-firebase-hooks/auth”;
import { auth } from “./firebase_config”;
  • Now, first we need to check if a user is signed in or not. To do that we use userAuthState function. This function retrieves and monitor the authentication state from firebase. It returns an array containing user, loading and error. In user, it returns firebase.User if a user is logged in or returns undefined. In loading, it returns a boolean value indicating if authentication state is still being loaded. Error returns any firebase error while trying to load state or returns undefined if there is no error. userAuthState accepts auth as a parameter which is an instance of the app we are monitoring that is our to do app.
  • So change the user in our main function in index.js file.
function Main(){ 
const [user] = useAuthState(auth);
return user? <App />:<SignIn />
}
  • Now in the userSignIn() which will be called in case user clicks on sign in button —
userSignIn = ()=>{ 
auth.signInWithPopup(
new firebase.auth.GoogleAuthProvider()
)}
  • This will enable us to sign in to our app using Google.
  • Only thing remaining in authentication part is to add a sign out option.To sign out simply use auth.signOut().
  • In app.js import auth from firebase_config file and write the sign out function —
function Signout(){
auth.signOut()
}

Step 5: Performing the CRUD operations

  • We will be working in app.js file now.
  • To add task in each users account we need to get the user id.
const userId = auth.currentUser.uid;

a) Add task to database

  • To add task to the database import db from firebase_config file.
  • Now, we need to create a reference to the database. A reference points to a location in the database. We can create a location with the reference or access the location if it already exists.
  • When we click on Add button we want the task to be added to the database.
db.collection(`users/${userId}/todos`)
  • This is a reference that will create a users field which will have a collection of users and each user will have set of tasks. Tasks will be added when we click on Add button. So to add a task we just need to call a add function —
db.collection(`users/${userId}/todos`).add({
inProgress: true,
task: task,
timestamp:firebase.firestore.FieldValue.serverTimestamp()
})
  • This will create an object with three properties. The property inProgress means whether task is completed or is in progress and timestamp is used to sort the task in a particular order.

b) Show added tasks on the screen

  • We need to show tasks when user is first signed in and when a new task is added then it should be displayed with the other tasks.
function getTodos(){ 
db.collection(`users/${userId}/todos`).
onSnapshot(function (querySnapshot){
setAllTasks( querySnapshot.docs.map((doc)=>(

{ id: doc.id,
task:doc.data().task,
inProgress:doc.data().inProgress
}
)
))
}
)
}
  • In the above function,we go to the location where we listen to the todos document using onSnapshot function. An initial call to the call back function specified inside the function creates a document snapshot with current content of the todos document. Then each time the document changes, a new snapshot is generated.
  • Here, the snapshot generated contains an array of the tasks present in database. These tasks are then added to the allTasks array.
  • We can now traverse the allTasks array to append the tasks on the DOM.
<div className=”show-tasks”> 
{ allTasks.map((task)=>{
return <ShowTask
key={task.id}
id={task.id}
task={task.task}
status={task.inProgress}
userId={userId}/>
})
}
</div>
  • ShowTask component will append the tasks —
  • To show tasks when user is signed in we will use useEffect. This will ensure that when user is logged in getTodos() gets called.
useEffect(() => { 
getTodos();
}, []) //[] stays blank to launch only on first launch of app.

c) Mark task as completed

  • To mark a task as completed we need to set the inProgress property of the task as false. So, we need to call update function to update inProgress. Inside ShowTasks component —
function toggleDoneButton(){ 
db.collection(`users/${userId}/todos`)
.doc(id)
.update({
inProgress:!status
}) }
  • Here we passed the task id to identify which task needs to be updated. Inside update function only the property that needs to be updated is specified.

d)Delete a task

  • To delete a task we need to pick the document with the task id and then call delete() to delete that document.
function deleteTask(){ 
db.collection(`users/${userId}/todos`)
.doc(id)
.delete();
}

That’s it! Its done now. You can add your own styling to it. This is a very basic to do app, you can add more features to it.

To view the source code visit here.

I hope it wasn’t too much. Thank you for reading this far.

References

[1] Firebase docs

--

--