This tutorial is outdated. We're currently working on an updated version. In the meantime, for instructions on building a chat app using CometChat, please visit our documentation.
App and web development have come a long way over the last few years. We use a lot of e-commerce apps every day such as Ebay, Amazon, and so on. Using the React CometChat UI Kit, Firebase backend services, you will learn how to build the Ebay clone.
Follow along the steps to build the Ebay clone that will allow users:
1. User Login/Registration
A way for end-users to login and register
A form for end-users to add goods/products they are selling
2. Products
Search page: Display goods/products on a listing screen
Product page: Display a single product and chat with the seller
3. Cart & Wishlist
Add an ‘Add to cart’ button on each product page so users can purchase multiple products at a time
Add a button to add products to the ‘Wishlist’
There’s no need to include payment functionality but do add buttons that redirect to a static page so there’s no break in the users flow.
4. Chat
Use the React UI Kit and select the right components
Add inbox page (only conversations in the navigation tab)
Add a way to launch chat for a particular product listing
Login the logged-in user to CometChat
Customize UI to match E-bay website
Add API call when a user registers so that the user is created in CometChat
Prerequisites
To follow this tutorial, you must have a degree of understanding of the general use of React.js. 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 ebay by running the following statement.
Step 3: you need to install some dependencies. Please get the list of dependencies from here, and then run
*Note: At this time of writing this tutorial, we are using the Firebase SDK with the version @8.9.1
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 "ebay-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** in the root folder of your project.
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 from being exposed online.
Setting Up Firebase Project
According to the requirements of the Ebay 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 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
Now, you need to go enable Firebase Realtime Database. We will 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 realtime 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 “REACT_APP_FIREBASE_DATABASE_URL” variable in your .env file with that value.
Database Url
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 read/write as you can see from the in the image below. Please do not forget to set the “.indexOn” for the “users”.
Database rules
In this project, we also need to upload the product’s image. 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 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. After finishing this step, you should see your Firebase credentials as follow, please update your .env file with your Firebase credentials.
Firebase credentials
Firebase Dashboard
Once you’re done registering the application, you’ll be presented with a screen containing your application credentials.
Data Structure - User
The above image describes the data structure of the users. A user will contain the following information:
avatar: the user’s avatar.
email: the user’s email.
fullname: the user’s full name.
id: the user’s id.
In this application, the end-users can upload the products that they want to sell. For this reason, we need to store the selling products on the Firebase Realtime Database. The below image describes the data structure of the products.
Data Structure - Product
CreatedBy: the id of the user who created the product.
Description: the product’s description.
Id: the product’s id.
Image: the product’s image.
Name: the product’s name.
Price: the product’s price.
Configuring Styling for the Application
Inside your project structure, open the index.css files and paste the codes here. index.css file will contain all CSS of the application.
Configuring Constants for the Application
We need to define a folder which is called “constants”. The constants folder contains all of the constants that are used in the application such as the firebase keys, the local storage keys, the routes. Please create the “storage” folder inside the “src” folder, and create the “firebase-keys.js” file, “storage-keys.js” file, the “routes.js” file. You can get the content of those files from here.
Configuring Images for the Application
In this project, we need to create a folder called “images” inside the root folder. The “images” folder is used to store all of the images that will be used to build the application. To get the images, you can refer to this link.
Creating React Context
In this application, we need to pass some data between the components. We can have 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” folder inside the “src” folder, and then create the “AppContext.js” file inside it. The full source code of the “AppContext.js” file can be found here.
user: it is used to store the authenticated information.
cometChat: it is used to store the CometChat instance.
Initializing CometChat for the Application
The below codes initialize CometChat in your app before it spins up. The AppContext.js file uses your CometChat API Credentials. We will get CometChat API Credentials from the .env file. Please do not share your secret keys on GitHub.
Configuring the Firebase File
You need to create a “firebase.js” file inside the “src” folder and you need to enable Firebase realtime database. This file is responsible for interfacing with Firebase authentication and database services. Also, it makes ready our email/password authentication service provider enabling us to sign in with google. Secret keys will be stored in the .env file. As mentioned above, please do not share your secret keys on GitHub. Please create the “firebase.js” file inside “src” folder. The full source code can be found here.
Creating Services
We should follow the DRY principle in our code. DRY stands for “do not repeat yourself”. It means that we should not duplicate the business logic. To avoid duplication in our code, we need to create some service files. Each file contains some methods that will be used to handle an individual aspect in our application, for example, showing the notification, creating the CometChat group, inserting the data to the Firebase Realtime Database service, and so on. Please create the “services” folder inside the “src” folder. Inside the “services” folder, please create the below files. For the content of each file, you can find here.
cart.js: handle actions related to the product cart.
cometchat.js: handle actions related to CometChat services.
firebase.js: handle actions related to Firebase services.
route.js: handle actions related to navigating between pages, routing.
storage.js: handle actions related to the local storage.
ui.js: handle actions related to the UI such as showing the notification, showing/hiding the loading indicator.
wishlist.js: handle actions related to the wishlist.
menu.js: it returns the list of menu items.
category.js it returns all of the brands and categories for the application.
Project Structure
The image below reveals the project structure. Make sure you see the folder arrangement before proceeding.
Project Structure
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 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. The full source code of the App.js file can be found here.
The Loading Component
The Loading Component
The loading component will be shown when the system performs some side effects such as interacting with Firebase or calling CometChat APIs, and so on. This component will be used to increase user experience. If we do not have this component, the end-users cannot know when the data is loaded successfully. Please create the “components” folder inside the “src” folder, and create the “common” folder inside it. The “common” folder is used to store the common components that will be used in different places in your application. After that, 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
The Login Component
This component is responsible for authenticating our users using the Firebase authentication service. It accepts the user credentials and either signs him up or in, depending on if he is new to our application. See the code below and observe how our app interacts with Firebase and the CometChat SDK. Please 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.
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 of 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 will discuss the sign-up component in the following section.
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 login function from the “cometchat.js” file, you can refer to the below code snippet for more information.
The withModal - Higher-Order Component
As mentioned above, we would like to show the SignUp component as a modal. Actually, we have multiple modals in the application, and we should avoid duplicating common functionalities such as showing/hiding the modals, and so on. To reuse the common logic, we can have several options. In this project, we will create a higher-order component called “withModal”. That higher-oder component helps us to avoid duplicating code and we can customize the UI for the modals. Please follow the below code snippet for more information. Please create the “Modal.js” file inside the common folder. The full source code can be found here.
The Sign Up Component
The SignUp 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 on Firebase by using the Firebase authentication service. 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 createAccount function from the “cometchat.js” file. You can refer to the below code snippet below for more information.
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. In this case, we are using React UI Kit v3.0. To do that, follow the next steps:
Step 1: Clone the CometChat React UI Kit Repository like so:
Step 2: Copy the folder of the CometChat Pro React UI Kit you just cloned into the src folder of your project:
Project Structure
React UI Kit Dependencies.
Step 3: Copy all the dependencies from the package.json file of the CometChat Pro React UI Kit folder and paste them in the dependencies section of the package.json file of your project.
Step 4: Save the file and install the dependencies like so: npm install
As soon as the installation is completed, you now 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
We need to have some private routes in our application. It means that the end-users cannot access those routes if they have not logged in to the application. To achieve that, we need to create the PrivateRoute component. The PrivateRoute component will check the authenticated information in the local storage, if the information is existing in the local storage, the users can access the private routes, and vice versa. Please create the “PrivateRoute.js” file inside the “common” folder. The full source code can be found here.
The Header Component
The Header component
The Header component is used to display the user’s avatar, the greeting, some menu items and the log out button. The full source code of the Header component can be found here.
The Logout Feature
The Logout Feature
After clicking the log out button, a confirm dialog will be displayed to ask the end-users whether they want to sign out from the application. To handle the logout process, the following steps will be executed:
Call the logout function of CometChat.
Remove the authenticated information from the global state, and the local storage.
Redirect the end-users to the log in page.
Please refer to the below code snippet for more information.
The Sell Component
The Sell Component
After the users click on the “Sell” item on the header component, the Sell component will be displayed as a modal. According to the above image, the users can choose the product’s image, and then input the product’s information including the product’s name, the product’s price, and the product’s description. In this case, we apply validation to validate the form such the the product’s price must be number, and other fields must be required.
After the users click on the “Create Product” button, the application will upload the product’s image, and insert the product’s information to the Firebase Realtime Database service. Please create the “sell” folder inside the “components” folder, and then create the “Sell.js” file inside it. The full source code can be found here.
The Home Component
The Home Component
The home component will take the responsibility for rendering the list of products. It will interact with the Firebase Realtime Database service, and then get the list of products. After that, it will pass the response to the Products component via props. We will discuss about the Products component in the following section. Please create the “home” folder inside the “components” folder, and create the “Home.js” file inside it. The full source code can be found here.
As you can see from the above code snippet, the Home component is using other components, and they are the home banner component, the home section component, and the home products component. We will talk about them in the following sections.
The HomeBanner Component
The HomeBanner Component
The home banner component is used to show the banner for the home page. Please create the “HomeBanner.js” file inside the “home” folder. The full source code can be found here.
The HomeSectionTitle Component
The HomeSectionTitle Component
The home section title component is used to show the title for the home section component, we will discuss about the home section component in the following part. Please create the “HomeSectionTitle.js” file inside the “home” folder. The full source code can be found here.
The HomeSection Component
The HomeSection Component
The home section component is used to show the popular brands and categories for the application. We create some hard-code data for the demo purpose. In the real life project, we should get that data from the APIs. We will get the data from the “category.js” file in the services folder. Please create the “HomeSection.js” file inside the “home” component. The full source code can be found here.
The HomeSectionItem Component
The HomeSectionItem Component
Each category/brand will be rendered by using the HomeSectionItem component, as you can see from the code snippet of the previous section, we render the list of categories/brands by using the map function, and each item will be passed to the HomeSectionItem component. Please create the “HomeSectionItem.js” file inside the “home” folder. The full source code can be found here.
The HomeProducts Component
The HomeProducts Component
The Home component will interact with the Firebase database to get the list of products, and then the home products will take the response via props. After that, the home products component will display the products by using the map function. Each item in the list will be passed to the HomeProductItem component, the HomeProductItem component will be discussed in the following part. Please create the “HomeProducts.js” file inside the “home” folder. The full source code can be found here.
The HomeProductItem Component
The HomeProductItem Component
As mentioned above, the home product item component is used to render each product in the products list. It will receive the product information via props and that information will be passed from the home products component. Please create the “HomeProductItem.js” file inside the “home” folder. The full source code can be found here.
The Search Component
The Search Component
The users can type the keywords on the search box, and then click on the “Search” button. For the tutorial purposes, the users will need to input the whole product name to search. The keyword will be saved to the local storage, the users will be redirected to the search result page. The search result page will be used to display the list of products that are matched to the keywords. We discuss it in the following section. Please create the “search” folder inside the “components” folder, and then create the “Search.js” file inside it. The full source code can be found here.
The Menu Component
The Menu Component
The menu component is used to show the list of menu items in the application, we get some hard-code data from the “menu.js” file in the service folder for the demo purpose. In the real-life project, we should get the data from the APIs. After getting the response, the menu component will show the list of menu items by using the map function and then pass each item to the MenuItem component that will be discussed in the following part. Please create the “menu” folder inside the “components” folder and then create the “Menu.js” file inside it. The full source code can be found here.
The MenuItem Component
The MenuItem Component
As mentioned above, each menu item will be rendered by using the MenuItem component, the MenuItem component will receive the item via props. Please create the “MenuItem.js” file inside the “menu” folder. The full source code can be found here.
The SearchProducts Component
The SearchProducts Component
After the users type something on the search box, and click on the search button, the users will be redirected to the search products page. The keyword will be saved to the local storage. After that, the search products component will get that keyword from the local storage, and then interact with the Firebase realtime database to get the list of products which are compatible with the keyword - we are searching by the product’s name. Please create the “SearchProducts.js” file inside the “search” folder. The full source code can be found here.
As you can see from the above code snippet, the search products component is using the search categories component to show the left sidebar, and it will render the list of products by using the map function. Following that, each product will be passed to the search product item component via props. We will discuss about all of them in the following section.
The SearchCategories Component
The SearchCategories Component
The search categories component is used to render the left sidebar for the search products component. We just get some hard-code data from the “category.js” file inside the service folder. After that, we pass each item to the SearchCategoryItem component via props. We will talk about it later. Please create the “SearchCategories.js” file inside the “search” folder. The full source code can be found here.
The SearchCategoryItem Component
The SearchCategoryItem Component
As mentioned above, each item in the list will be rendered by using the search category item component, the search category item component will receive the item via props from the search categories component, please create the “SearchCategoryItem.js” file inside the “search” folder. The full source code can be found here.
The SearchProductItem Component
The SearchProductItem Component
Each item in the search results will be rendered by using the search product item component. The search product item component will receive the product via props. Please create the “SearchProductItem.js” file inside the “search” folder. The full source code can be found here.
The ProductDetail Component
The ProductDetail Component
After clicking on any item on the product list, the product detail component will be shown as a modal. The product detail information will be shown. On the other hand, the users can choose the number of quantity, and then add to cart. Aside from that, the users can add the product to the wishlist, or chat with the seller.
To add the product to the cart, we use the addToCart method from the “cart.js” file in the “services” folder. Following that, to add the product to the wishlist, we use the addToWishlist method from the “wishlist.js” file in the “services” folder. If the users click on the “Chat with seller” button, the users will be redirected to the chat page, that page will be discussed in the following section.
Please create the “detail” folder inside the “components” folder, and then create the “ProductDetail.js” file inside it. The full source code can be found here.
The Cart Component
The Cart Component
As mentioned above, after the users add a product to the cart, the product will be saved to the local storage. If the users click on the “cart” item on the header, the users will be redirected to the cart page. The cart component will get the products from the local storage, and render them by using the map function. After that, each product will be passed to the CartItem component. The CartItem component will be discussed in the following section. Please create the “cart” folder inside the “components” folder, and create the “Cart.js” file inside it. The full source code can be found here.
The CartItem Component
The CartItem Component
As mentioned above, each product in the cart will be rendered by using the CartItem component. each product will be passed to the CartItem component via props. Please create the “CartItem.js” file inside the “cart” folder. The full source code can be found here.
To remove a product from the cart, we call the remove function from the cart service, and update the state to reload the list.
The Wishlist Component
The Wishlist Component
According to the requirements, the product can be added to the wishlist. We will save the products to the local storage with the “wishlist” key. The wishlist component will get those products from the local storage, and render them by using the map function. Each product will be passed to the WishlistItem component. it will be discussed in the following section. Please create the “wishlist” folder inside the “components” folder, and then create the “Wishlist.js” file inside it. The full source code can be found here.
The WishlistItem Component
The WishlistItem Component
As mentioned above, each product in the wish list will be rendered by using the WishlistItem component. the product will be passed to the WishlistItem component via props. Please create the “WishlistItem.js” file inside the “wishlist” folder. The full source code can be found here.
To remove any product from the list, we will call the remove function from the wishlist service, and then update the state to reload the page.
The Payment Component
The Payment Component
On the cart page, the users can click on the payment button, the cart in the local storage will be cleared, and the users will be redirected to the payment page. For learning purposes, we will not integrate any payment services. Please create the “payment” folder inside the “components” folder, and create the “Payment.js” file inside it. The full source code can be found here.
The Chat Component
The Chat Component
In this application, the users can chat with others. For this reason, if the users click on the “chat” item on the header, the users will be redirected to the chat page. In the Chat component, we use the CometChatUserListWithMessages component from the CometChat UI Kit. Please create the “chat” folder inside the “components” folder, and create the “Chat.js” file inside it. The full source code can be found here.
The Chat With Seller Component
The Chat With Seller Component
On the product detail page, the users can click on the “Chat with Seller” button. After clicking on that button, the users will be redirected to the chat with seller page. The seller here is the person who uploaded the product for selling. In this ChatWithSeller component, we use the CometChatMessages from the CometChat UI Kit and pass the seller id to the chatWithUser prop. Please create the “ChatWithSeller.js” file inside the “chat” component. The full source code can be found here.
Wrapping Up
In conclusion, we have done an amazing job in developing a Ebay clone by leveraging React.js, Firebase, CometChat SDK, and React UI Kit. You’ve been introduced to the chemistry behind Ebay and how the CometChat SDK makes the Ebay 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.
Hiep Le
CometChat