Build an Appointment Scheduler using Node, Firebase, and Vonage

Vonage Dev
8 min readMar 14, 2022

--

Introduction

In this tutorial, we are going to build an appointment scheduler web application using Node.js, Express, Firebase, and the Vonage Messages API. The GitHub repository for this project is also available, feel free to clone it here.

Set Up Firebase

To start, let’s create a new project from the Firebase console.

  • Click on add a new project
  • Give your project a meaningful name, for instance vonage appointment scheduler
  • Check if you like the unique identifier id for your project (it is used in your Realtime Database URL, Firebase Hosting subdomains, and more. It cannot be changed after project creation)
  • Click on the button to continue
  • Select if you want to enable analytics. We won’t in this tutorial
  • Click on the button to create the project
  • Wait for the project to be created
  • Once the project is ready, click to continue. You will be taken to your project’s console view
  • Set the Billing type by clicking on the gear icon, followed by Usage and Billing, then on the Details & Settings tab and modify the plan to use Blaze. This pay-as-you-go plan is required when using a third-party API

Install Firebase Tools CLI

From your terminal, install the Firebase tools with NPM if you don’t already have them by typing: npm install -g firebase-tools. Next, type firebase login. This will open a window in your browser which will either authenticate you automatically (if you're already logged in) or ask you for your credentials. Once that's complete you now have the Firebase CLI installed.

Create and Set Up a RealTime Database

Now it’s time for us to create the NoSQL database instance that will hold the appointment slots’ information. Our app will include a view where a user will be able to make or cancel appointments. As the person interacting with the view picks an appointment date and time, that slot will be added or removed from the Firebase RealTime Database.

  • Click on “Create Database”
  • Select the Realtime Database location where your data will be stored and click on next
  • Select if you will use the database in locked or test mode. For this example, I am using the test mode
  • Click enable

Import the Database JSON File

Let’s import an example database which already contains some allocated slots, and from which you’ll be able to add and remove future slots. You can create a file called myAppointments.json containing the JSON in the snippet below, and then import this file from the console.

Add the Database Rules

The Firebase Realtime Database Rules determine who can access your database, how your indexes are built, and how your data is structured.

  • From the Firebase console on the Realtime database view, you can see “Rules”, click on that tab. You’ll be taken to a screen that will allow you to edit your rules
  • Copy and paste the rules from the below code snippet to your console in order to set the myAppointments collection to be indexed by the date field.
  • Click on Publish

Create the Project Structure

By the end of this tutorial, this is roughly how your project structure will look like. In the following steps, we will create the files that will build up the content, appearance, functionalities, and handle the services we will use.

Setup

  • Create the project folder and cd into it: mkdir appointment-scheduler && cd appointment-scheduler
  • Initialize NPM: npm init. This command prompts you to add information about the project
  • Install the dependencies: npm install @vonage/server-sdk dotenv uuid express firebase-admin firebase-functions
  • Type firebase init. Since we already created a project in the dashboard, you can select Use an existing project which will prompt you to choose the desired project. You can see my example with my project id vonage-appointment-scheduler below. I also chose to use the Realtime Database feature

Create the HTML Content

Did you know that the HTML input element has many type options for date and time selection? For instance, we have: date, datetime-local, time. For this tutorial, we will use <input type="datetime-local">. This approach is perhaps not as robust as using date-time library, as there can be some inconsistencies, but it works for the purpose of this tutorial. The user will be able to book slots every 5 minutes ending in 0 or 5 for instance 18:00 is bookable but 18:01 is not.

Add CSS Styling

For this demonstration web app, we’ll add some styling to center the contents on the page, and also display a red ✖ in case the input is invalid and a ✓ in case it is valid.

  • Create the public/styles.css file
  • Paste in the below CSS code
  • The FIREBASE_DATABASE_URL can be found on the Firebase console
  • The VONAGE_API_KEYand the VONAGE_API_SECRET can be found in the Vonage Dashboard
  • The VONAGE_FROM_NUMBER contains the number, name, or brand that will appear as the sender of the message
  • The VONAGE_TO_NUMBER is the number that will receive the SMS messages

Create the JavaScript file `server.js`

We will create the server.js to tell Express how to handle the requests posted by the UI. I'll show you step by step how we will build it. You can find the complete server file here.

Our web app will use express and it will read the static files we previously created from the public folder.

Add the Service Account

A Firebase service account can be used to authenticate various Firebase features, for our project we will use the Firebase Admin SDK to access our Database URL.

  • From the Firebase Console click on the gear and select the Service Account tab
  • Click on the button to generate key
  • Add the generated file to the root of your project and rename it to serviceAccountKey.json
  • Copy and paste the Admin SDK configuration snippet to your project, as you can see in the following step of this tutorial, to initialize Firebase. We are using ${process.env.FIREBASE_DATABASE_URL to read the URL from the .env file but it's the same Database URL found on the Firebase Admin SDK configuration.

Initialize Firebase

We use initializeApp to create and initialize a Firebase app instance that will use the /myAppointments Firebase database instance we have previously created and populated from the Firebase Console.

Initialize the Vonage API object

We create the instance of the Vonage client class, initializing it with the Vonage API Key and Secret that you have previously added to your .env file.

Create the getDateTime() Function

The HTML input type datetime-local is formatted as YYYY-MM-DDThh:mm. So we will write a function to separate the date from the hour by splitting it on the character T. For instance in the example 2018-06-12T19:30 we'd have 2018-06-12 for the date and 19:30 for the hour.

Create the `/appointment` endpoint

It’s time to create the /appointment endpoint to handle the POST requests for creating an appointment. This endpoint will check if the slot is available, it will add the slot to the Firebase database, and finally, it will send an SMS confirmation back to the user's phone using the Vonage Messages API.

You may have noticed that much of the functionality within the request handler has not yet been implemented, so let’s now expand on the stubs for the required functionalities.

Check Slot Availability

This function validates if a slot is available by checking if the slot already exists in the database. We are querying ref.orderByChild('date'). Queries are allowed to order one key at a time. We have previously defined our index via the .indexOn on the Firebase Rules for better performance. And then we make use .once('value') to listen for exactly one event of the value, and then it stops listening.

Add the Slot to the Database

The following function addToDatabase() adds the slot and a code to the Firebase database. This code is required to cancel the appointment.

Send an SMS with the Appointment Information

Finally, once the slot is reserved, an SMS confirmation is sent back to the user with the message Meeting booked at ${time} on date: ${date}. Please save this code: ${code} in case you'd like to cancel your appointment. as you can see in the function sendSMStoUser().

Finalize the Business Logic

The piece of code below is responsible to call the previously created helper functions. If the slot is available, the user will have their slot added to the database and have the SMS sent back to them. Otherwise, they will be requested to choose a different time slot.

Cancel the Appointment `/cancelAppointment`

Let’s create the /cancelAppointment endpoint handling the POST requests for canceling an appointment from the database by using a code provided by the user that they received upon scheduling their appointment.

Listen to the Port

Finally, the app will be listening on the specified port, if run locally this will be accessible on https://localhost:${port}. In this URL you can interact with the UI of this demo application and check the slots being added/ removed on the Firebase console web page.

Test it Out

  • Install all the dependencies npm install
  • Run the NPM command to execute the project npm run start
  • Navigate to http://localhost:3000
  • Add and remove appointment slots and see them being added and removed from the Firebase Realtime Database

Conclusion and Next Steps

Today you saw how to build an appointment scheduler demo web app. Now you can go ahead and add fancier styling and other functionalities. You can take what you learned here to create many appointment schedulers may it be for a gym or for a vaccination slot — let the creativity flow!

Reach out to us on Twitter and join our community on Slack.

--

--

Vonage Dev
Vonage Dev

Written by Vonage Dev

Developer content from the team at Vonage, including posts on our Java, Node.js, Python, DotNet, Ruby and Go SDKs. https://developer.vonage.com

No responses yet