React UI Kit

How to Build an eBay Clone App

Follow this tutorial step by step to build the best eBay clone app using React & Firebase.

Hiep Le • Feb 17, 2022

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

  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 "ebay-clone".

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 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

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

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

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 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 “REACT_APP_FIREBASE_DATABASE_URL” variable in your .env file with that value.

Database Url

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

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

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. After finishing this step, you should see your Firebase credentials as follow, please update your .env file with your Firebase credentials.

Firebase credentials

Firebase credentials

Firebase Dashboard

Firebase Dashboard

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

Data Structure - User

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

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

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

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

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 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

Project Structure

React UI Kit Dependencies.

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

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

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

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

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 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 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 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

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 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

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 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

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

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

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 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

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

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

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

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

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

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

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

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

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

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

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.