App and web development have come a long way over the last few years. We use a lot of HIPAA compliant telemedicine applications and one of them is Zocdoc. the most widely used features is live chat because the patients and the doctors need to connect and talk to each other. Using the CometChat React Native UI Kit, React Native, and Firebase, you will learn how to build one of the Zocdoc clone with minimal effort. This tutorial will help you to create the Zocdoc clone in React Native, Firebase, and CometChat.
We should cover the following topics in this tutorial:
A way for end-users to login and register a patient.
A way for end-user to sign-up/login as a doctor.
Display list of all their patients and appointment.
Display patient profile with past diagnosis and history (We will display static content for the demo/learning purposes).
Ability to chat with a patient via text, voice, and video.
Display doctors on a listing screen.
Display a single doctor profile.
Ability to set an appointment.
Ability to chat with the doctor via text, voice, and video.
Use the CometChat React Native UI Kit.
To follow this tutorial, you must have a degree of understanding of the general use of React Native. This will help you to improve your understanding of this tutorial.
Installing the App Dependencies
Step 1: You need to have Node.js installed on your machine.
Step 2: Create a new project with the name zocdoc-clone with version 0.63.3 by running the following statement.
Step 3: Copy the dependencies from here and run the following statement.
Step 4: In this project, the patients and the doctors can make voice/video calls. Therefore, we need to use CometChat services. To make the CometChat calling component work, please follow this link.
Step 5: Run cd to the ios folder then run pod install to install the pods. Once pods are installed run cd .. to go back to the root folder.
Step 6: We do not want the keyboard overlap the input elements on the Android devices. For this reason, we need to add the below line to the AndroidManifest.xml file.
*Note: If you are running the application on IOS simulators and you do not see the icons, you need to run react-native link react-native-vector-icons command to fix that.
Configuring CometChat SDK
Head to CometChat Dashboard and create an account.
Register a new CometChat account if you do not have one
After registering a new account, you need to the log in to the CometChat dashboard.
Log in to the CometChat Dashboard with your created account
From the dashboard, add a new app called "zocdoc-clone".
Create a new CometChat app - Step 1
Create a new CometChat app - Step 2
Select this newly added app from the list.
Select your created app
From the Quick Start copy the APP_ID, REGION, and AUTH_KEY, which will be used later.
Copy the the APP_ID, REGION, and AUTH_KEY
Navigate to the Users tab, and delete all the default users (very important).
Navigate to Users tab and delete all the default users
Navigate to the Groups tab and delete all the default groups (very important).
Navigate to Group tab and delete all the default groups
Create a file called **env.js** in the root folder of your project.
Import and inject your secret keys in the **env.js** file containing your CometChat in this manner.
10. Make sure to include **env.js** in your gitIgnore file from being exposed online.
Setting Up Firebase Project
According to the requirements of the ZocDoc clone, you need to let users create a new account and login to the application, Firebase will be used to achieve that. Head to Firebase to create a new project and activate the email and password authentication service. This is how you do it:
To begin using Firebase, you’ll need a Gmail account. Head over to Firebase and create a new project.
Firebase provides support for authentication using different providers. For example, Social Auth, phone numbers, as well as the standard email and password method. Since you will be using the email and password authentication method in this tutorial, you need to enable this method for the project you created in Firebase, as it is by default disabled.
Under the authentication tab for your project, click the sign-in method and you should see a list of providers currently supported by Firebase.
Next, click the edit icon on the email/password provider and enable it.
Enable Firebase Authentication with Email and Password
Now, you need to go enable Firebase Realtime Database. We will use Firebase Realtime Database to store the information of the users in the application. Please refer to the following part for more information.
Choose “Realtime Database” option
Click on “Create Database"
Select location where you real-time database will be stored
Select “Start in test mode” for the learning purpose
Please follow the guidance from Firebase. After following all steps, you will see the database URL. If you just need to update the “FIREBASE_REALTIME_DATABASE_URL” variable in your “env.js” file with that value.
On the other hand, your Firebase real-time database will be expired in the future. To update the rules you just need to select the “Rules” tab and update the date/time in milliseconds as you can see in the image below.
Update Firebase Realtime Database Rules
In this project, we also need to upload the post’s images, and user’s avatars. Therefore, we have to enable the Firebase Storage service, the Firebase Storage service helps us store the assets files including images, videos and so on. To enable the Firebase Storage service, please follow the below steps
Enable Firebase Storage Service
Click on the “Next” button
Click on the “Done” button
Update the rules
For the learning purposes, we need to update the rules of the Firebase Storage service. It means that everyone who can access the application, can upload to the Firebase storage.
Now, you need to go and register your application under your Firebase project. On the project’s overview page, select the add app option and pick web as the platform.
Once you’re done registering the application, you’ll be presented with a screen containing your application credentials.
Please update your created “env.js” file with the above corresponding information. Now your “env.js” file should look like this:
As you can see in the below image, the user information contains the avatar, email, bio, full name, id, and role.
Data Structure - User
In this application, the patients can set the appointments with the doctors. Therefore, we need to create data structure for each appointment. The appointment will contain the doctor’s id, doctor’s image, doctor’s name, appointment’s id, patient’s id, patient’s image, patient’s name.
Data Structure - Appointment
Congratulations, now that you're done with the installations, we will add the CometChat UI to our application in the next section.
Add The CometChat UI To Our Application
Before we can use the CometChat Pro React Native UI kit, we need to add it in our project so that we can reference it. In this case, we are using React Native UI Kit v3.0. To do that, follow the next steps:
Step 2: Copy the cometchat-pro-react-native-ui-kit folder to your source folder.
Copy the project into your source folder
Step 3: Please check your current package.json file, if your package.json file did not have the dependencies as you can see in the peer dependencies section, please copy all the peer dependencies from package.json into your project's package.json and install them using npm install
Copy all peer dependencies and install them
Step 4: According to the requirements, after a patient set an appointment with a doctor. We need to make them as friends by using the CometChat API. Therefore, we can show the list of friends by using the CometChatUserList component. To show the list of friends, we need to configure the UIKitSettings.js file; please update the below line in the UIKitSettings.js file.
As soon as the installation is completed, you now have access to all the React Native UI Components. The React UI kit contains different chat UI components for different purposes as you can see in the documentation here. It includes:
Project Structure - Client Side
The image below reveals the project structure. Make sure you see the folder arrangement before proceeding.
The Project Structure
components: This folder stores components that will be used in the application.
images: This folder contains images that will be used in the application such as audio icon, video icon, settings icon and so on.
env.js: This file stores configuration of the application such as Firebase and CometChat configuration.
context.js: This file helps us store the state that will be shared across all components without passing down at every level. For this reason, we can avoid props drilling.
Configuring Images for the Application
As mentioned above, we need to create a folder which is called “images”. This folder is used to store images in the application. To get images for the application, you can get from here.
Configuring the Firebase File
You need to create a “firebase.js” file inside your source folder. This file is responsible for interfacing with Firebase services such as Firebase Authentication service, Firebase Realtime Database, Firebase Storage. Secret keys will be stored in the env.js file. As mentioned above, please do not share your secret keys on GitHub.
Creating React Context
In this application, we need to pass some data between the components. We can save several options to achieve that such as using state management libraries, RxJS, and so on. However, we can get in-built support from React by using the React Context API. the React Context API helps us pass data through the component tree without passing down at every level. Please create the “context.js” file inside the “src” folder. The full source code of the “context.js” file can be found here.
Initializing CometChat for the Application
The below codes initialize CometChat in your app before it spins up. The App.js file uses your CometChat API Credentials. We will get CometChat API Credentials from the .env.js file. Please do not share your secret keys on GitHub.
Actually, App.js does not contain only the above code. It also contains other business logic of the application. The full source code of App.js file can be found here.
Create the Permissions for the Application
In this application, we need to provide the calling features. For this reason, the user needs to provide some permissions for the application such as accessing the camera, recording video, writing/reading to external storage, and so on. Because we are wanting the application to run on both Android and IOS. Therefore, this section will help you know how to make the application request permissions from the end-users.
For Android, you need to write the “getPermissions” function and then call it inside the “useEffect” of the App.js file. You can refer to the code snippet below for more information.
For IOS, you need to add the following content to your Info.plist file.
The App.js File
The App.js file is responsible for rendering different components by the 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. On the other hand, it will be used to initialize CometChat. The full source code of the App.js file can be found here.
The Login Component
The Login Component
This component is responsible for authenticating our users. It accepts the user credentials and either signs him up or in, depending on if he is new to our application. You can refer to the below steps to understand the authentication flow.
Step 1: The users input their credentials (email/password).
Step 2: The application validates the credentials.
Step 3: If the credentials are valid, the application calls the Firebase Authentication service by using those credentials.
Step 4: If the Firebase Authentication service returns the user’s aid the application continues to log in to the CometChat using the returned uid.
Step 5: If the CometChat service returns the valid response, the application calls the Firebase Realtime Database service to get the authenticated information, and then store that information in Async Storage. Therefore, when we need to get the authenticated information, we just need to get the data from Async Storage instead of calling the Firebase Realtime Database service.
See the code below and observe how our app interacts with the Firebase Authentication service, and the CometChat SDK. Please create the “components” folder, and create the “Login.js” file inside it. The full source code can be found here.
We store the authenticated Information to the async storage for further usage such as getting that information in different places in the application, prevent the end-users come back to the login page after signing in to the application.
To login to the CometChat, we call the cometChat.login function, you can refer to the below code snippet for more information.
We will discuss the sign-up component in the following section.
The Sign Up Component
The Sign Up Component
The sign-up component will help end-users to register new accounts. This component will do two things. The first thing is to register new accounts by calling the create user API. Aside from that, it also registers new accounts on CometChat by using the CometChat SDK. Please create the “SignUp.js” file inside the “components” folder. The full source code can be found here.
To create a new CometChat account, we call cometChat.createUser function. You can refer to the below code snippet below for more information.
The Home Component
The Home Component - The Appointments List, if the current user is a doctor
The Home Component - The Doctors List, if the current user is a patient
As you can see in the images above, if the current user is a doctor, the Home component will show the appointments list and if the current user is a patient, the Home component shows the list of doctors so that the patient can connect to all the doctors in the application. To show the corresponding list, we need to create two components - The Appointments component, and the Doctors components. Those components will be discussed in the following section. To create the Home component, please create the “Home.js” file inside the “components” folder. The full source code can be found here.
The Doctors Component
The Doctors Component
As mentioned above, if the current user is a patient, the Home component shows all the doctors in the application via the Doctors component. The Doctors component will call the Firebase Realtime Database service to get all the users which are having “Doctor” role. After that, the Doctors component will update the “doctors” state, and then display the list of doctors by using the FlatList component. We would like to breakdown our components into smaller components. For this reason, to render each doctor in the list, we will use the DoctorItem component that will be discussed in the following part. Please create the “Doctors.js” file inside the “components” folder. The full source code of the Doctor component can be found here.
The DoctorItem Component
The DoctorItem Component
Each doctor in the list will be rendered by using the DoctorItem component. The DoctorItem component accepts two props - item (the doctor’s information) and onItemClick (a callback function that will be triggered after the users click on any item). This component just take the responsibility for rendering the information of each doctor. Please create the “DoctorItem.js” file inside the “components” folder. The full source code can be found here.
The Appointments Component
The Appointments Component
If the current user is a doctor, the list of appointments will be showed via the Appointments component. The Appointments component will call the Firebase Realtime Database service to get the appointments list for the current doctor. After that, it will update the “appointments” state and then show the data using the FlatList component. The good new is if the current user is a patient and then that user clicks on the “alarm” icon on the header, he/she can also view the list of his/her appointments. It means that, we can reuse this component in different places in the application. You can refer to the image below.
Reuse the Appointments Component in different pages
Please create the “Appointments.js” file inside the “components” folder. The full source code can be found here.
The AppointmentItem Component
The Appointment Item
Each appointment in the list will be rendered by using the AppointmentItem component. This component is similar to the DoctorItem component. It accepts three props - item (the appointment information), onItemClick (a callback function that will be triggered after selection any item on the list), isDoctor (a boolean variable is used to determine the current user is a doctor, or not). This component jus take the responsibility for rendering the appointment information. Please create the “AppointmentItem.js” file inside the “components” folder. The full source code can be found here.
The Doctor Detail Component
The Doctor Detail Component
After the patients select a doctor from the doctors list, the users will be redirected to the doctor detail page. On that page, the Doctor Detail component is used to render the detail information of the selected doctor. On the other hand, the patient can set an appointment with that doctor by clicking on the “Set Appointment” button. To set an appointment, the application will do two things. The first thing is to insert the new appointment to the Firebase Realtime Database service. Following that, the application call the CometChat API to make the doctor and the user be friends so they can talk to each other in the application. Please create the “DoctorDetail.js” file inside the “components” folder. The full source code can be found here.
To create a CometChat friend, we need to call the CometChat API as follow:
The PatientDetail Component
The PatientDetail Component
This component renders the detail information of the patient, after the doctors select any item on the appointments list, the doctors will be redirected to the patient detail page in which the selected patient information will be displayed via the PatientDetail component. The PatientDetail component takes the item that were passed from the appointments list component and then display the data. Please create the “PatientDetail.js” file inside the “components” folder. The full source code can be found here.
The Conversations Component
The CometChatMessages Component
The CometChatUserListWithMessages Component
After the users click on the “chat” icon on the header, the users will be redirected to the chat page in which the patients and the doctors can talk to each other. In this component, we will use two components from the CometChat React Native UI Kit - CometChatUserListWithMessages and CometChatMessages. We need to create a new navigation stack to navigation between different components in the CometChat React Native UI Kit. Please create the “Conversations.js” file inside the “components” folder. The full source code can be found here.
The Logout Feature
The Logout Feature
To logout from the application, the end-users click on the power button, a confirmation dialog will be displayed, if the end-users would like to sign out, the users just need to click on the “Ok” button. After that, the application will do some clean-up actions before redirecting the users to the home page. Please refer to the below code snippet for more information.
In conclusion, we have done an amazing job in developing an ZocDoc clone by leveraging React Native, Firebase, and CometChat React Native UI Kit. You’ve been introduced to the chemistry behind ZocDoc and how the CometChat makes the ZocDoc clone 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 and that you were able to successfully add mentions into your React chat app. Jump into the comments and let me know your experience.
About the Author:
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.