A Light-weight and Easy-to-deploy App With React and Firebase

John Guest
The Startup
Published in
5 min readAug 30, 2020

How I used React and Firebase to create a low-dependency and light-weight configuration with user authentication and state management

This is not intended to be a how-to but a small set of examples I think best exemplify how React and Firebase easily work together.

React is the perfect tool for exploring new web software and cool web services like Firebase. React and Firebase, alone supply everything you need to build and deploy a lightweight application with state, a database, and user authentication. Here I will go into some examples of how to use Firebase for the backend and how to replace Redux with React Hooks.

I recently put together a WhatsApp clone based on this video from Clever Programmer. This application is a great example of how to integrate React Hooks with Firebase to manage state and user authentication in a low-configuration and efficient design.

The configuration of this project is in stark contrast to past projects of mine in which I have built the backend myself. I do feel the need to remain in the practice of building REST APIs and backend logic and I do feel tremendous gratification after a successful compile and deploy of an app like that, however, if your intention is to explore the bleeding edge of front-end tech and get it online easily then Firebase is a great solution.

Let’s start with how I manage state without Redux. I start in “src/StateProver.js”

I use the React Context API. It creates a data layer to wrap the application and works very much like Redux without adding to your dependencies. Passing a variable for “children” (this will be our <App/> component), a reducer, and an initial state to the createContext() function, we create an “enhanced component” and assign it to a value of a function that returns a component. This is called a “higher-order component” and it is named <StateProvider/>, it is used similar to Redux <Provider/>. This is the data layer that we use throughout the application. On line 11 I create the container that allows me to pass actions to my reducer to update the state with useContext().

The reducer used for StateContext is just, as a reducer should be, a plain-old JavaScript function. You can see here that reducer.js below, exports an “initialState”, an “actionTypes” object, and the reducer function. This architecture functions the same as Redux but it just looks and feels cleaner if you ask me.

Firebase

Firebase is a platform developed by Google for creating mobile and web applications. It was originally an independent company founded in 2011. In 2014, Google acquired the platform and it is now their flagship offering for app development. Wikipedia

Getting started on Firebase is easy and the console is simple enough. Here I would like to focus on the code in my application that allows me to deploy and host the app. By importing the Firebase package you can initialize your application and database as well as create the tools you will need to accomplish the easiest user authentication method I have ever seen. Going back to my Login.js file and the signIn() function.

You can see that I have imported auth and provider from firebase.js. These variables are containers for functions of the Firebase package I initialized in firebase.js and imported. When the user clicks the “Sign in with Google” button, signIn() is called. I use another function of Firebase called signInWithPopup(). This takes a function “provider” as an argument. We create the provider as a container for GoogleAuthProvider() which gives the user a pop-up to select the account they want to use and returns a JSON object of that user's information.

The really fun part of this application is the Firestore database. You can set up the database on firebase.com and then create a container for a function called firestore() that is the link between the app and the database.

Here is an example of how easy it is to call your database and access collections within. Here you will also see that I have incorporated hooks to access specific entries in the database in the order I need to update the state of the component.

I am getting roomId from a hook, useParams(). It allows me to access the params of the URL which contains the unique room id. As roomId is passed to the dependency array in useEffect(), it is run whenever roomId changes. What I wanted to point out was how I sort through the database. Remember that db is a container for our firestore() function. On line 31 I begin adding all the messages in a particular chat to the state of the component. I call db.collectio(“rooms”) which selects the “rooms” collection. I then select the room I want by passing in the roomId. I use the timestamp column of my database to organize the messages. The method onSnapShot() is a realtime listener that is run whenever the database updates. That’s right. This is a method that fires on your app every time the database updates. This allows for real-time two-way communication between your client and server.

In using React and Firebase you find many examples of code that looks like this. Simple to use and easy to integrate. These two tools are all I needed to build this great application.

--

--

John Guest
The Startup

“The Web as I envisaged it, we have not seen it yet. The future is still so much bigger than the past.” — Tim Berners-Lee