How to Build a Rideshare Site with React.JS (Ola Cabs Clone)

Everyday people use ride share sites such as Ola, Uber, Lyft, Grab, Gojek, and Be. One of the most widely used features of these sites is live chat. In this tutorial you will use CometChat communications SDK, Firebase, and Mapbox to build an Ola clone, allowing users to to book rides and chat with their drivers, either via text or voice calling.

Hiep Le • Sep 7, 2022

Every day people use ride share sites such as Ola, Uber, Lyft, Grab, Gojek, and Be. One of the most widely used features of these sites is live chat. In this tutorial you will use  CometChat communications SDK, Firebase, and Mapbox to build an Ola clone, allowing users to to book rides and chat with their drivers, either via text or voice calling.

Prerequisites

To follow this tutorial, you need to have Node.js installed on your machine and be familiar with the basics of React.js.

Installing the App Dependencies

  1. Create a new project with named ola-clone using the command: npx create-react-app ola-clone

  2. Copy the dependencies from here into your package.json file, and run npm install

*Note: At this time of writing this tutorial, we are using the Firebase SDK with the version @8.9.1

Configuring the CometChat SDK

You will need to create an account with CometChat in order to use the SDK to take advantage of the realtime communication services our application will depend on.

You can create an account by following these steps:

  1. Head to CometChat Dashboard and create an account

s deeaeeaceafbbcedeabaeddcc image

  1. Log in to the CometChat dashboard

s cebffcbfcceecafeccccae screenbshotb batb

  1. Add a new app named ola-clone

s deeaeeaceafbbcedeabaeddcc image

s cebffcbfcceecafeccccae vlioyzp

  1. Select your app from the list

s cebffcbfcceecafeccccae bscncnjn

  1. Navigate to the Users tab, and delete all the default users

s deeaeeaceafbbcedeabaeddcc screenbshotb batb

  1. Navigate to the Groups tab and delete all the default groups

s deeaeeaceafbbcedeabaeddcc screenbshotb batb

  1. From the Quick Start copy the APP_ID, REGION, and AUTH_KEY

s cebffcbfcceecafeccccae qhrbreb

  1. Create a file called .env in the root folder of your project.

  2. Import and inject your secret keys in the .env file containing your CometChat and Firebase in this manner.

Make sure to include .env in your gitIgnore file to prevent it being included in your git repository

Setting Up a Firebase Project

Please follow the below steps to set up Firebase.

Creating a New Firebase Project

  1. Go to https://firebase.google.com and click on the Sign in

react-js-ola-cabs-clone-img-1

  1. Sign in to Firebase using a Gmail account

react-js-ola-cabs-clone-img-2

  1. Click on Go to console

react-js-ola-cabs-clone-img-3

  1. Click on Add project to create a new Firebase project

react-js-ola-cabs-clone-img-4

  1. Input the project name, tick the checkbox to accept the Firebase terms, and then click on Continue

react-js-ola-cabs-clone-img-5

6. Click on Continue

react-js-ola-cabs-clone-img-6

  1. Tick the two checkboxes shown below and click Create project

react-js-ola-cabs-clone-img-7

Note:

You may not see the above image, You may see the below image. If you see the below image, please select your account and then click on the "Create project" button.

react-js-ola-cabs-clone-img-8

  1. Firebase will handle the remaining tasks for us and we wait until everything has been set up successfully

react-js-ola-cabs-clone-img-9

  1. Click on Continue

react-js-ola-cabs-clone-img-10

Setting Up Firebase Realtime Database

We will use Firebase’s Realtime Database service as the data store for our application. To set up a Firebase Realtime Database service, follow the steps below:

  1. Expand the Build menu, if it is not expanded, and click on Realtime Database

react-js-ola-cabs-clone-img-11

  1. Click on Create Database

react-js-ola-cabs-clone-img-12

  1. Choose the Realtime Database location and click on Next

react-js-ola-cabs-clone-img-13

  1. Select Start in test mode and click on Enable

react-js-ola-cabs-clone-img-14

Note:

After finishing all of the above steps, you will see the below screen.

react-js-ola-cabs-clone-img-15

We need to use the users email address to select their information, therefore, we need to update the Firebase rules so that this field is indexed to make searching faster

react-js-ola-cabs-clone-img-16

Congratulation! We have set up the "Firebase Realtime Database" service successfully. In the following section, we will set up the "Firebase Authentication" service together.

Setting Up the Firebase Authentication Service

We will be using Firebase’s Authentication Service to manage users accounts. The service will be configured so that users need to provide a username (email address) and password in order to use the application.

  1. Expand the Build menu and click on Authentication

react-js-ola-cabs-clone-img-17

  1. Click on Get Started

react-js-ola-cabs-clone-img-18

  1. Select Email/Password

react-js-ola-cabs-clone-img-19

  1. Enable Password and Email authentication, then click on Save

react-js-ola-cabs-clone-img-20

Setting Up Firebase Storage

When creating new accounts, end-users can upload their avatars. We need to enable the "Firebase Storage" service to store these files.

  1. Expand the Build menu and click on Storage

react-js-ola-cabs-clone-img-21

  1. Click on Get started

react-js-ola-cabs-clone-img-22

  1. Select Start in test mode, then click on Next

react-js-ola-cabs-clone-img-23

  1. Click on Done

react-js-ola-cabs-clone-img-24

  1. For our purposes, we need to update the rules which control who has access to the data stored in the service. Update your storage rules to match the image below and click on the Publish to apply changes

react-js-ola-cabs-clone-img-25

Adding a New Web App in Firebase

In order to interact with the different Firebase services, we need to create a set of credentials for our application to use by creating a new Web Application in Firebase.

  1. Click on the Settings icon and choose the Project Settings

react-js-ola-cabs-clone-img-26

  1. Scroll down to the bottom of the page and click on the web icon

react-js-ola-cabs-clone-img-27

  1. Input your App’s name and click on Register app

react-js-ola-cabs-clone-img-28

  1. You will be presented with your applications Firebase credentials. These need to be added to the .env file. To finish creating the new web app, click on Continue to console

react-js-ola-cabs-clone-img-29

Setting Up Mapbox

For our ride sharing app, we need to use the leaflet-routing-machine library to draw a route between two locations. We will use Mapbox as an OSRM service.

Follow the steps below to setup Mapbox:

  1. Head to Mapbox and create an account. After signing in to Mapbox, you will be redirected to the page in which you will see the default public token.

react-js-ola-cabs-clone-img-30

  1. Add the Mapbox default public token to your .env file

Note: If the Mapbox platform requires a credit card/debit card to create an account and you do not have one, please feel free to use the below Mapbox API key for the demo and learning purposes.

pk.eyJ1IjoiaGllcHRsIiwiYSI6ImNrc2xuc2F5bDFhcXgyd3BlYTNhYnlkZnIifQ.9uRZZTvD7TChE2NxXZT-iw

Styling for the Application

In order to style your application, you can copy the style sheet here and add the rules to your index.css file.

React Context API

In order to pass data between components, we are going to used the React Context API. This API helps us pass data through the component tree without passing it down each level. Copy the context.js file here and add it to the src folder for the project.

Initializing CometChat

The app.js file retrieves your CometChat API Credentials from the the environment in order to initialise the CometChat SDK, so that it can be used by the application. The full source code can be found here.

Configuring the Firebase File

You need to create a firebase.js file inside the src folder, this file is responsible for interfacing with  the Firebase authentication and database services. In the snippet below we load the firebase credentials from the environment and initiate the different Firebase services. The full source code can be found here.

Creating Services

Services help us centralise our application logic and to avoid duplication in our code. Each service provides methods that will be used to handle an individual aspect of our application, for example, inserting the data to the Firebase Realtime Database service, interacting with the CometChat services,  and working with the UI elements.

Create a services folder inside the src folder. Inside the services folder, create the below files. For the content of each file, you can find here.

cometchat.js: this file contains functions that will be used to interact with the CometChat services such as creating a new account, login to the CometChat platform and so on. The full source code can be found here.

firebase.js: this file contains some functions that will be used to interact with the Firebase services. The full source code can be found here.

ui.js: this file contains functions that are related to the UI such as showing/hiding the loading indicator. The full source code can be found here.

Project Structure

The image below demonstrates the project structure. Make sure you see the folder arrangement before proceeding.

s efdccccafdbacccdface screenbshotb batb bam

Now, let's make the rest of the project components as seen in the image above.

The App.js File

The App.js file is responsible for rendering different components for given routes. For example, it will render the login page if the user has not logged in, yet or it renders the home page if the user has signed in to the system. The full source code of the App.js file can be found here.

Components

Create a components folder inside the src folder, and create a common folder inside it. The common folder is used to store the common components that will be used in different places in your application.

The Loading Component

s ffeaaeadfeacfbddbfbcffbecc screenbshotb batb bam

The loading component will be shown when the system performs actions such as interacting with Firebase or calling CometChat APIs. You need to create the Loading.js file inside the common folder. The full source code of the loading component can be found here.

The Login Component

s ffeaaeadfeacfbddbfbcffbecc screenbshotb batb bam

This component is responsible for authenticating our users using the Firebase authentication service. It accepts the user credentials and either signs them in or registers a new account. Create the Login.js file inside the login folder. The full source code can be found here.

The above code indicates that we are using withModal as a higher-order component. This higher-order component will be used to reuse the code for showing and hiding the custom modal. In this case, we want to show the sign-up modal to let end-users register new accounts.

We store the authenticated information in local storage for further use, so that we can access it in different places in the application, preventing the end-users come back to the login page after signing in to the application.

To login to the CometChat, we call the login function from the cometchat.js file, you can refer to the below code snippet for more information.

The withModal - Higher-Order Component

In our application, there are multiple places where we want to display components in a modal. In order to reuse the common logic to show and hide the modal we will create a higher-order component called withModal. That higher-order component helps us to avoid duplicating code each place we want to use a modal within the application. Create a Modal.js file inside the common folder. The full source code can be found here.

The Sign Up Component

s ffeaaeadfeacfbddbfbcffbecc screenbshotb batb bam

The sign-up component will be used for end-users to register new accounts. This component will do two things. It will register new accounts on Firebase using the Firebase authentication service, and it also registers new accounts on CometChat using the CometChat SDK.

Create a register folder inside the components folder, and create the SignUp.js file inside it. The full source code can be found here.

To create a new CometChat account, the createAccount() function  is called, which is loaded from the cometchat.js file. You can see the function below.

Add the CometChat UI to our Application

Before we can use the CometChat Pro React UI kit, we need to add it in our project so that we can reference it.

  1. Clone the CometChat React UI Kit Repository: git clone https://github.com/cometchat-pro/cometchat-pro-react-ui-kit.git

  2. Copy the folder of the CometChat Pro React UI Kit you just cloned into the src folder of your project:

s efdccccafdbacccdface screenbshotb batb bam

s babddbffbbbbbaffcccedaffeb react ui kit dependencies

  1. Copy all the dependencies from the package.json file in the CometChat Pro React UI Kit folder and paste them in the dependencies section of the package.json file of your project.

  2. Save the file and install the dependencies using npm install

Once the installation is completed, you will have access to all the React UI Components. The React UI kit contains different chat UI components for different purposes as you can see in the documentation here. It includes:

1. CometChatUI

2. CometChatUserListWithMessages

3. CometChatGroupListWithMessages

4. CometChatConversationListWithMessages

5. CometChatMessages

6. CometChatUserList

7. CometChatGroupList

8. CometChatConversationList

The Private Route Component

To ensure users can’t access features of the application without logging in, we need to add some private routes and check a users authentication before the application can load. This will be doe through a PrivateRoute component. The PrivateRoute component will check the authenticated information in the local storage, if the information exists the users can access the private route if not they will be redirected to login.

Create the PrivateRoute.js file inside the common folder. The full source code can be found here.

The Header Component

p

The Header component, will show the app’s name, user’s avatar, greeting, and the logout button.

When users click on the Logout button, a confirmation dialog will be shown. If the users click on the Ok button, the application will log out from the application by calling the cometChat.logout() function. After that, we will update the user state to null, and remove the authenticated information from localstorage.

Create the Header.js file inside the common folder. The full source code of the Header.js file can be found here.

The AddressPicker Component

p

The AddressPicker component allows users to input their pickup and destination locations. The application will suggest the locations based on the keywords they enter. If the users want to change their pickup or destination location, they just need to click on the locations that they want to change. After selecting the pickup and destination locations, a route will be drawn on the map and a confirmation dialog will be shown (that dialog will be a component which is called RequestRide component). We will develop these features in the next sections.

Create a folder named address-picker inside the components folder and add the AddressPicker.js inside it. The full source code of the AddressPicker.js file can be found here.

The RequestRide Component

s ffeaaeadfeacfbddbfbcffbecc screenbshotb batb bam

As mentioned above, after the users select their pickup and destination locations, we will show the RequestRide component as a modal. The RequestRide component, will have a title, close icon, content and two buttons (Change and Requesting a ride now). If the users clicks on the Change button, the RequestRide component will be closed and they can change their pickup and destination locations. However, if the user clicks on the Requesting a ride now button, the application will insert the ride request in to the Firebase Realtime Database service.

Create a request-ride folder inside the components folder. The full source code of the RequestRide component can be found here.

The RideList Component

p

The RideList component component will be used to show a list of requesting rides, this component is only available for drivers and if the current user is a driver, the user will see this component instead of the address picker component.

When the users clicks on the Accept button, we will update the ride request on the Firebase Realtime Database. There are four states of a request (waiting, accepted, canceled and done). Following that, a component, which is called RideDetail component will be shown on both sides (the user’s side and the driver’s side).

Create a ride-list folder inside the components folder and add the RideList.js file inside it. The full source code can be found here.

The RideDetail Component

p

After a driver accepts a ride request on the RideList component, that ride request’s status will be changed to accepted and the RideDetail component will be shown on both sides (the user’s side and the driver’s side). On the user’s side, the RideDetail component will be used to show the driver’s information. And on the driver’s side, the RideDetail component will be used to show the user’s information.

On the driver’s side, there are three buttons - chat, cancel, and finish. If the driver clicks on the chat button, that driver will be redirected to the chat page where they can chat with the passenger. If the driver clicks on the cancel button, the current ride request’s status will be changed to canceled and the application will update that request in the Firebase Realtime Database service. If the driver clicks on the finish button, the current ride request’s status will be changed to done and the application will update that request in the Firebase Realtime Database service.

On the user’s side, there are two buttons - chat and cancel. If the user clicks on the chat button, that user will be redirected to the chat page where they can chat with the driver. If the user clicks on the cancel button, the current ride request’s status will be changed to canceled and the application will update that request on the Firebase Realtime Database service.

Create the ride-detail folder inside the components folder and add the RideDetail.js file inside it. The full source code of the RideDetail.js file can be found here.

The Home Component

p

In the previous sections, we have defined the AddressPicker, RideList, and RideDetail components. It is time to import and use those components in the Home component. The Home component is responsible for rendering the map, and displaying the corresponding components based on different scenarios. For example, if the current user is a passenger and that user has not requested any ride, yet, the Home component will show the AddressPicker component. If the current user is a driver, the RideList component will be used to show the list of available ride requests. If a request is accepted by the driver, the RideDetail component will be shown on both sides (the driver’s side and the passenger’s side).

Create the home folder inside the components folder and add the Home.js file. The full source code can be found here.

Note: To display the map correctly, we need to import leaflet CSS in the index.html file, the content of the index.html will be like this.

The Chat Component

s ffeaaeadfeacfbddbfbcffbecc screenbshotb batb bam

From the RideDetail component, both the driver and the passenger can chat with each other by clicking on the chat icon. Once the driver and the passenger click on the chat icon, they will be redirected to the Chat page. The Chat page uses the CometChat UI Kit. The CometChat team has handled everything for us and we just need to import the components that we want to use. This means, we can add chat, voice, and video calling features with minimal effort.

In this case, we will import the CometChatMessages component from cometchat-pro-react-ui-kit, which we have integrated before. The CometChatMessages component accepts a prop (chatWithUser) and the prop’s value should be the CometChat id of the user that we want to chat with. For example, on the driver’s side, the value of the chatWithUser prop should be the passenger’s id. And on the passenger’s side, the value of the chatWithUser prop should be the driver’s id.

Create the chat folder inside the components folder and add the Chat.js file inside it. The full source code can be found here.

Conclusion

You can now run your app with the command: npm run start

In conclusion, we have done an amazing job in developing an Ola clone app by leveraging React.js, Firebase, CometChat SDK, and React UI Kit. You’ve been introduced to the chemistry behind the Ola clone app and how the CometChat services make the Ola clone app buildable.

You have seen how to build most of the chat functionalities such as real-time messaging using CometChat. I hope you enjoyed this tutorial.

Hiep Le

CometChat

Hiep Le is a software engineer. He takes a huge interest in building software products and is a full-time software engineer. Most of his work is focused on one thing - to help people learn.

Try out CometChat in action

Experience CometChat's messaging with this interactive demo built with CometChat's UI kits and SDKs.