How JavaScript Works: Understanding modular and functional programming with JavaScript and Firebase 9

Lawrence Eagles
SessionStack Blog
Published in
10 min readAug 4, 2022

This is post # 70 of the series, dedicated to exploring JavaScript and its building components. In the process of identifying and describing the core elements, we also share some rules of thumb we use when building SessionStack, a JavaScript tool for developers to identify, visualize, and reproduce web app bugs through pixel-perfect session replay.

Introduction

Firebase is a backend-as-a-service (BAAS) platform that provides back-end services such as database, authentication, file storage, cloud functions, hosting, etc. And Firebase provides simple APIs that front-end and mobile developers can consume to plug these services into their applications.

Also, Firebase handles all the server-side logic and heavy lifting so that front-end and mobile developers do not go through the hassle of setting up a custom-backed infrastructure.

So, Firebase is an efficient alternative to setting up custom back-end infrastructure using tools like MongoDB, Mongoose, Node, and Express. Thus, Firebase enables front-end and mobile developers to focus on their areas of expertise. And consequently, it is loved by front-end and mobile developers.

In this article, we will learn about modular and functional programming by working with Firebase 9.

Compared to Firebase 8, Firebase 9 adopts a modular and functional approach, enabling us to import only the Firebase functions we need in our project. And we can also optimize our code with tree-shaking by using module bundlers like Wepback and Rollup.

So, using Firebase 9 in this functional way means more optimized output code and smaller file size. And we will learn more about this in action in a subsequent section as we build our application.

Scaffolding the client-side JavaScript application

Our app will be built with plain JavaSript, HTML, and Tailwind CSS. And we will bundle the app with Webpack.

We will get started by scaffolding our JavaScript application using NPM. In your terminal, run the following code from your project directory:

npm init -y

Now install your app’s dependencies and dev dependencies by running:

Next, we enable ES module and setup up our NPM scripts by adding ”type”: “module” to the package.json properties. And also updating the script property of the package.json file as seen below:

By installing all the dependencies and dev-dependencies in the previous step, we have installed Webpack, Tailwind CSS, and Firebase. Now let’s configure each of them.

Configure Webpack

To configure Webpack create a webpack.config.js file in the root directory and add the following code to it:

Configure Tailwind CSS

To configure Tailwind CSS, run: npx tailwindcss init -p in the terminal to create a tailwind.config.js file and a postcss.config.js file — since we are adding Tailwind with postCSS. Note because we enabled ES module in our application, there will be some compatibility issues with the tailwind.config.js and the postcss.config.js files because these files use CommonJS module. So to solve this, change the extension of both files to .cjs. Now replace the content of the tailwind.config.cjs file with the following code:

Next, we add the app’s entry point and HTML boilerplate. To do this, create a src directory in the root directory. And create an index.js file and an index.html file inside the src directory.

Add the following code to the index.html file:

Also, in the src directory, create a main.css file and add the Tailwind CSS code below:

@tailwind base;
@tailwind components;
@tailwind utilities;

Note in the boilerplate above, we are linking to the bundled JavaScript and CSS file.

To test our application we need to first bundle it by running:

npm run build

Now open another terminal and run:

npm start

And we get:

Building A Book Application

To build the book application we will start by configuring Firebase and synchronizing our client app with the Firebase project.

Configure Firebase

In this section, we will learn how to configure firebase and build our application backend. I have created a well-commented boilerplate to initialize Firebase. Add the following code to the `index.js` file:

In the above, we initialize the app using the initializeApp function. The initializeApp function takes the firebaseConfig object as an argument and uses it to connect our JavaScript app to our Firebase back-end.

Also, we connected our app to a firebase database using the getFirestore function and we imported all the functions we need from firestore. We will learn more about these functions later in this section.

Now we need to create a Firebase project, a database, and configure an app. Creating a Firebase project will give us a config object that enables us to connect our app to your Firebase project resource.

To create a new Firebase project, follow the steps below:

  1. visit console.firebase.google.com/ and click on Add project. And you get:

2. Enter your project name and click continue.

3. You can optionally enable Google analytics for your project.

4. Click on create project. And when Firebase finishes creating your project, click on continue to go to the project’s console.

Now you need to register an app with your project. To do this, follow the steps below:

  1. Click the Web icon </> on the project console to launch the setup workflow as seen below:

2. Add your app’s nickname and click on Register app.

2. Copy the config object code provided for you and update the config object in the index.js file as seen below:

The next step is to set up a database and connect to that database from the JavaScript application. To do this, follow the steps below:

  1. On the sidebar of your Firebase console, click on Firestore Database
  2. Click on Create database and select start in test-mode and click Next
  3. Select firestore location and click on Enable to create a database

The Firebase database consists of collections and documents.

And a collection here refers to a collection of certain data-type. So since we are creating a book store application, we will name the collection books because it is a collection of a data type called book.

Click on start collection and you get:

Type books as the collection ID, then click on Next.

Now you get a form to add new documents — as seen below:

Firebase documents consist of document ID, fields, data-type, and value.

Create a document with the code below:

{
title: “JavaScript The Good Parts”,
author: “Douglas Crockford”
}

In Firebase, the fields are the properties. So in the field input, add title. And in the value input, add “JavaScript The Good Parts”. Then click on Add field and add the author field and its value.

Also, click on Auto-ID to generate an ID and click on save. You can later add other books by following this pattern.

The next step is to connect this database to your JavaScript application and get data from the books collection. And to do this, we need to import the three functions from the firestore part of the Firebase library.

Fetch And Render Data

In this sub-section, we will learn how to fetch data from our Firebase database and render them in the UI. To this, create a utils folder in the src directory and add these files to the utils folder: createElem.js, renderBooks.js, and index.js.

In the createElem.js file, add the following code:

And in the renderBooks.js file, add the following code:

Lastly, in the index.js file, add the following code:

The createElem function is a helper function that enables us to create HTML elements using JavaScript. And the renderBooks function renders a list of books using the createElem function.

Now import the renderBooks function to our index.js file below the comment:

// import UI rendering logic.

To render our data to the view, we will subscribe to the book collection by using the firestore collection function. And this function enables us to actively listen to the book collection and update the UI automatically whenever things change.

The collection function takes a collection reference as its first argument. And we can get a reference to the books collection by adding this line of code to the index.js file — below the // Ref collection comment:

const colRef = collection(db, ‘books’);

Now we subscribe to the books collection by adding the code below to the index.js file — below the // getRealtime data comment:

In the code above, the getSnapshot function takes a callback function as its second argument. And this callback function receives a snapshot of the books collection as its argument and invokes the renderBooks function — passing the books array as an argument.

Thus when the books collection changes, the renderBooks is invoked, and the UI is updated automatically.

To check if we are successfully fetching data from firebase, run the build script and start the server, and we get:

Deleting Data

To delete data, we use the delete function. And this function takes two arguments:

  • A document reference is gotten by using the doc function
  • A Callback function.

We will use event delegation to listen for click events on a book title. And once this occurs, we call the delete function passing the document reference as its argument.

To do this, add the following code below in the index.js file in the src directory:

In the renderBooks function, we added the id for each book by using the HTML 5 data attribute. So we can easily get the clicked book by using: event.target.dataset.id in our listener.

Now when we click on a book, it gets deleted automatically.

Creating and Updating Data

To create documents, we will use addDoc function, and to update a document, we will use the updateDoc function. And to implement the add document and update document features, we will add event listeners that listens for a submit event in both the add-book form and the update-book form. So once the submit event occurs, the appropriate function is invoked to handle the event.

To implement this, add the following code to the index.js file in the src directory, to get the DOM elements of the forms:

const addForm = document.querySelector(‘#add-book’);

const updateForm = document.querySelector(‘#update-book’);

Below the // Handle add new document comment, add the following code to add an event listener to the add-form form:

Also, below the // Handle update document comment, add the following code to add an event listener to the update-form form:

Now run the build script and start the dev server. The app is complete, and all CRUD operations work correctly. In the next section, we will deploy our app using firebase hosting.

Hosting The Book Store Application

Firebase Hosting is straightforward to use and set up. To host our application follow the steps below:

  1. First, install the Firebase CLI by running the code below:
    npm install -g firebase-tools
  2. Log in and list your projects with the code below:

// login
firebase login

// list projects
firebase projects:list

And we get:

3. Connect the local project to a Firebase project by running:

firebase init hosting

Now from the on-screen instruction, select use an existing project and choose a Firebase project.

Next, specify a public directory — in this case, it is the dist directory.

And configure the app as a single-page application.

Firebase would automatically add rewrite configurations for you.

Also, at the end of the configuration, Firebase will create some files: firebase.json file,firebaserc in the root directory, and an index.html file in the dist folder.

But this does not contain our application markup. To fix this, delete the contents of the index.html file created by Firebase — — in the dist folder. And copy the contents of the index.html file in the src directory into the index.html file in the dist folder.

Then update the link to the CSS and JS files as seen below:

// Link to CSS
<link href=”main.css” rel=”stylesheet”>

// Link to JS
<script type=”module” src=”bundle.js”></script>

Before we deploy the app, run:

firebase deploy — only hosting

And when the deployment is complete, Firebase gives you a hosting url. And you can access the app using this url.

Conclusion

In this article, we have learned about Firebase base the backend as a service platform. And by building and developing the book application with Firebase 9, we learned how to build a modular application using functional programming.

Lastly, if you are interested in the source code of the book store application, you can get it on Github.

So although the functional programming paradigm enables us to build modular applications and leverage optimization techniques such as tree-shaking, it should be complemented with proper testing. And even if we feel we’ve tested everything before the release it is always necessary to verify that our users have a great experience with our product.

A solution like SessionStack allows us to replay customer journeys as videos, showing us how our customers actually experience our product. We can quickly determine whether our product is performing according to their expectations or not. In case we see that something is wrong, we can explore all of the technical details from the user’s browser such as the network, debug information, and everything about their environment so that we can easily understand the problem and resolve it. We can co-browse with users, segment them based on their behavior, analyze user journeys, and unlock new growth opportunities for our applications.

There is a free trial if you’d like to give SessionStack a try.

SessionStack replaying a session

Interested in more about JavaScript? Check out all “How JavaScript works” publications here.

--

--