TUTORIALS

How to Build a Clubhouse Clone App

Hiep Le

View GitHub Repo
April 14, 2022

App and web development have come a long way over the last few years. We use a lot of social applications, and audio-based applications every day. Using the CometChat SDK, React Native, and Firebase, you will learn how to build one of the Clubhouse clone. This tutorial will help you to create the Clubhouse clone in React Native, Firebase, and CometChat.

We should cover the following topics in this tutorial:

1. Users

  • Register, login, and logout functionality.
  • Functionality to search and follow other users.

2. Rooms

  • Functionality to create and edit rooms.
  • Ability to join and leave rooms.

3. Audio

  • All rooms to have audio conferencing functionality.

4. Feed

  • A wall to display all active rooms.

5. Notifications

  • Someone joins their club.
  • Someone follows them.

Prerequisites

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 clubhouse with version 0.63.3 by running the following statement.
  • Step 3: Copy the dependencies from here and run the following statement.

*Note: The firebase package version should be 9.x.x.

  • Step 4: 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.

*Note: You need to increase the minimum target version for ios in Podfile to 11. For more information about how to setup CometChat in Android and IOS, you can refer to this link.

*Note: In this application, we need to load SVG files. For this reason, we used the react-native-svg and react-native-svg-transformer libraries. Therefore, we need to update the metro.config.js file as follows.

Configuring CometChat SDK

  1. Head to CometChat Dashboard and create an account.
Register a new CometChat account if you do not have one
Register a new CometChat account if you do not have one
  1. 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
Log in to the CometChat Dashboard with your created account
  1. From the dashboard, add a new app called "clubhouse".
Create a new CometChat app - Step 1
Create a new CometChat app - Step 1
Create a new CometChat app - Step 2
Create a new CometChat app - Step 2
  1. Select this newly added app from the list.
Select your created app
Select your created app
  1. 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
Copy the the APP_ID, REGION, and AUTH_KEY
  1. 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 Users tab and delete all the default users
  1. Navigate to the Groups tab and delete all the default groups (very important).
Navigate to Group tab and delete all the default groups
Navigate to Group tab and delete all the default groups
  1. Create a file called **env.js** in the root folder of your project.
  2. 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 Clubhouse 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
Firebase

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.

Firebase Authentication

Next, click the edit icon on the email/password provider and enable it.

Enable Firebase Authentication with Email and Password
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
Choose “Realtime Database” option
Click on “Create Database"
Click on “Create Database"
Select location where you realtime database will be stored
Select location where you realtime database will be stored
Select “Start in test mode” for the learning purpose
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.

Database Url
Database Url

On the other hand, your Firebase real-time database will be expired in the future. Aside from that, we need to set the .indexOn for some fields that we want to query. To update the rules you just need to select the “Rules” tab as follows.

Update Firebase Realtime Database Rules
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
Enable Firebase Storage Service
Click on the “Next” button
Click on the “Next” button
Click on the “Done” button
Click on the “Done” button
Update the rules
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 to 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.

Firebase Dashboard
Firebase Dashboard

Once you’re done registering the application, you’ll be presented with a screen containing your application credentials.

Firebase 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, list of followers, full name, id.

Data Structure - Users

In this application, the end-users can create rooms. Therefore, we need to store the rooms information in the Firebase Realtime Database.

Data Structure - Rooms

A room will contain the id, the title, and the information of the person who created that room.

On the other hand, the users can see the list of notifications such as someone joins their rooms, someone follows them.

Notifications page
Notifications page

The below image demonstrates the data structure of notifications in the Firebase Realtime Database.

  • notificationId: the id of the notification
  • notificationImage: the image of the notification.
  • notificationTitle: the content of the notification.
Data Structure - Notifications

Congratulations, now that you're done with the installations, we will add the CometChat UI to our application in the next section.

Project Structure - Client Side

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

The Project Structure
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.

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.

Setting Up Images

To get the images that have been used in this application, please refer to this link. Please create the images folder inside the “src” folder, and copy all of the images from the above link.

Setting Up the Firebase.js File.

In this application, we need to interact with Firebase services. Therefore, we need to have the firebase.js file. Please create the firebase.js file inside the root folder. Please refer to the below code snippet for the content of the firebase.js file. The full source code can be found here.

Setting Up Common Services

In this application, we do not want to violate the DRY - don’t repeat yourself principles when writing the code. For this reason, we create some common services so that we can reuse them in different places. Please create the “services” folder in the root directory. The “services” folder will contain all of the service files in the Clubhouse clone. This folder can be found here.

  • firebase.js: it will contain different functions that will be used to interact with the Firebase services such as inserting new data to the Firebase Realtime Database, or uploading files to the firebase Storage, and so on. Please create the “firebase.js” file inside the “services” folder. The full source code can be found here.
  • ui.js: this file will contain functions that are related to the UI such as showing the alert, and so on. Please create the “ui.js” file inside the “services” folder. The full source code can be found here.
  • notification.js: this file will contain functions that are related to the notification feature. Please create the “notification.js” file inside the “services” folder. The full source code 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.

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.

*Note: Please create some empty component to avoid the errors, we will write code inside them in the following sections. Here is the list of empty components that should be created.

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 inside the root directory and create the “login” folder inside the “components” folder, and create the “Login.js” file inside the “login” folder. The full source code can be found here.

We store the authenticated Information to the local 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 “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, we call cometChat.createUser function. You can refer to the below code snippet below for more information.

The Search Component

The Search Component
The Search Component

According to the requirements, the users can find other users and follow them. To achieve that, we need to create the Search component. If we click on the button on the top left corner of the home page. The following steps will be applied to get the list of users based on the input values.

  • Step 1: We need to listen to the onChange event of the search input.
  • Step 2: Whenever the users are typing on the search input, we will update the corresponding state.
  • Step 3: Because the state will be updated at step 2, we need to write the useEffect to listen to the state changes.
  • Step 4: Inside the useEffect, if the keywords are not empty, we will call the searchUsers function.
  • Step 5: After getting the response from the searchUsers function, we need to transform a little bit because we just want to show the list of users who the current user has not followed, yet. On the other hand, we will not show the current user.
  • Step 6: After transforming the data at step 5, we will update the users state and render the list of users by using the FlatList component.
  • Step 7: We define the renderUser function to render each item in the list.
  • Step 8: We also handle the event when the users click on the follow button of any item in the list. We create the follow function. The follow function will update the corresponding state, send a notification to the selected user, and show the alert message.

Please create the “search” folder inside the “components” folder and create the “Search.js” file inside it. The full source code can be found here.

The Home Component

The Home Component
The Home Component

The home component will be used to display the list of created rooms. On the other hand, the home component also contains the “Start a Room” button, if we click on that button, we will be redirected to the “Create Room” page in which we can create a new room. We will talk about that component in the following section. To develop the home component, we follow the below steps:

  • Step 1: We can the useEffect and it will be triggered whenever the home page has been loaded.
  • Step 2: Inside that useEffect, we call the getRooms function.
  • Step 3: After getting the response from the getRooms function, we will update the corresponding state - the rooms state.
  • Step 4: We will render the list of rooms by using the FlatList component.
  • Step 5: We define the renderRoom function to render each item in the list.
  • Step 6: We also handle the event when the users click on any item in the list. That user will join the created CometChat group - each room will be correspond to a CometChat group, we will redirect the users to the room detail page. We will talk about that page in the following section. If the current user is the owner of the selected group, we will show a confirmation dialog with two options - view and edit. If the user clicks on the view option, he/she will be redirected to the room detail page like the above flow. If he/she clicks on the edit button, he/she will be redirected to the edit room page where the user can update the room’s information.

Please create the “home” folder inside the “components” folder and create the “Home.js” file. The full source code can be found here.

To join the CometChat group, we need to use the CometChat services, please refer to the below code snippet for more information.

The Create Room Component

The Create Room Component
The Create Room Component

After the users click on the “Start a Room” button on the home page, the users will be redirected to this page. On this page, the users can input the room’s title and click on the “Create Room” button, to create a new room. To develop the create room component, please follow the below steps:

  • Step 1: We need to listen to the onChange event of the search input.
  • Step 2: Whenever the users are typing on the search input, we will update the corresponding state.
  • Step 3: We need to handle the event when the users click on the “Create Room” button. After the users click on that button, the createRoom function will be triggered. Inside the createRoom function, we will insert the new room information to the Firebase Realtime Database, and we also create a new CometChat group because we will create the audio call feature between members in the same room. To achieve that feature, we need to use the CometChat services. For this reason, we need the CometChat group.

Please create the “room” folder and create the “CreateRoom.js” file inside it. The full source code can be found here.

To create a new CometChat group, we will use the CometChat service, please follow the below code snippet for more information.

The Edit Room Component

The Edit Room Component
The Edit Room Component

If the current user selected a room and he/she is the owner of that room. A confirmation dialog will be shown with two options - view and edit. If the user clicks on the edit option, he/she will be redirected to the edit room page. On this page, the users can input the room’s title and click on the “Edit Room” button, to update the selected room. To develop the edit room component, please follow the below steps:

  • Step 1: We need to listen to the onChange event of the search input.
  • Step 2: Whenever the users are typing on the search input, we will update the corresponding state.
  • Step 3: We need to handle the event when the users click on the “Edit Room” button. After the users click on that button, the editRoom function will be triggered. Inside the editRoom function, we will update the selected room information to the Firebase Realtime Database, and we also update the corresponding CometChat group.

Please create the “room” folder and create the “EditRoom.js” file inside it. The full source code can be found here.

To update the selected CometChat group, we will use the CometChat service, please follow the below code snippet for more information.

The Notifications Component

The Notifications component
The Notifications Component

The Notifications component will be used to show the list of notifications for the current user. Such as when someone has joined the room or followed the current user. To develop the Notifications component, please follow the below steps:

  • Step 1: We need to create the useEffect that will be triggered when the page has been loaded.
  • Step 2: Inside that useEffect, we call the getNotifications function.
  • Step 3: After getting the response from the getNotifications function, we will update the notifications state.
  • Step 4: We render the list of members by using the FlatList component.
  • Step 5: We define the renderNotification function to render each item in the list.

The Room Detail Component

The Room Detail Component
The Room Detail Component

As mentioned above, on the home page, after the users click on any item in the list. The users will be redirected to the room detail page. On the room detail page, we will show the list of members in the group. On the other hand, we also have the “Join Call” button. After clicking on that button, the users will be redirected to the call page and can talk to other members in the same group. The develop the home detail page, we need to follow the below steps:

  • Step 1: We need to create the useEffect that will be triggered when the page has been loaded.
  • Step 2: Inside that useEffect, we call the getMembers function.
  • Step 3: After getting the response from the getMembers function, we will update the members state.
  • Step 4: We render the list of members by using the FlatList component.
  • Step 5: We define the renderMember function to render each item in the list.
  • Step 6: We need to handle the event when the users click on the “Join Call” button - the joinCall function.
  • Step 7: We also listen when a new member joins the group or a member’s left the group by using the CometChat service.

Please create the “RoomDetail.js” file inside the “room” folder. The full source code can be found here.

To get the list of members in a CometChat group, we use the CometChat services, please follow the below code snippet for more information.

To listen when a new member joins the group or a member’s left the group by using the CometChat service. You can refer to the below code snippet.

The Call Component

The Call Component
The Call Component

On the room detail page, the users can click on the “Join Call” button, The call UI will be shown, we use the CometChat services, and the CometChat services will do everything for us. Please create the “call” folder inside the “components” folder and create the “Call.js” file inside it. 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.

Wrapping Up

In conclusion, we have done an amazing job in developing a Clubhouse clone by leveraging React Native, Firebase, and CometChat SDK. You’ve been introduced to the chemistry behind Clubhouse and how the CometChat makes the Clubhouse 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 build a Clubhouse clone app.

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.

Related Posts

No items found.
No items found.

Try Us for Free 

For as Long as You Like!