How to Build an eBay Clone App
Follow this tutorial step by step to build the best eBay clone app using React & Firebase.
App and web development have come a long way over the last few years. We use a lot of aggregator business model apps every day such as AirBnb, Uber, Grab and so on. Using the React CometChat UI Kit, Firebase backend services, you will learn how to build the AirBnb clone.
Follow along the steps to build the AirBnb clone that will allow users:
1. User Login/Registration
2. Home Page
3. Chat
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.
*Note: At this time of writing this tutorial, we are using the Firebase SDK with the version @8.9.1
10. Make sure to include **.env** in your gitIgnore file from being exposed online.
According to the requirements of the Airbnb 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.
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.
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.
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.
In this project, we also need to upload the house’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
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.
Once you’re done registering the application, you’ll be presented with a screen containing your application credentials.
The above image describes the data structure of the users. A user will contain the following information:
In this application, the hosts can upload the houses. For this reason, we need to store the houses on the Firebase Realtime Database. The below image describes the data structure of the houses.
Inside your project structure, open the index.css files and paste the codes here. index.css file will contain all CSS of 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 “constants” 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.
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.
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.
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.
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.
- cometchat.js: Handles actions related to CometChat services.
- firebase.js: Handles actions related to Firebase services.
- route.js: Handles actions related to navigating between pages, routing.
- storage.js: Handles actions related to the local storage.
- ui.js: Handles actions related to the UI such as showing the notification, showing/hiding the loading indicator.
The image below reveals the project structure. Make sure you see the folder arrangement before proceeding.
Now, let's make the rest of the project components as seen in the image above.
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 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.
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.
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 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.
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:
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
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 is used to display the app’s icon, 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.
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:
Please refer to the below code snippet for more information.
After the users click on the “Create” item on the header component, the Create component will be displayed as a modal. According to the above image, the users can choose the house’s image, and then input the house’s information including the house’s name, the house’s price, and the house’s description. In this case, we apply validation to validate the form such the the house’s price must be number, and other fields must be required.
After the users click on the “Create” button, the application will upload the house’s image, and insert the house’s information to the Firebase Realtime Database service. Please create the “create” folder inside the “components” folder, and then create the “Create.js” file inside it. The full source code can be found here.
The home component will take the responsibility for rendering the background image, and some text to make our UI be more attractive, we do not have the business logic that needs to be handled here. 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.
The users can type the keywords on the search box, and then click on the “Search” button. 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 houses 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 search result component will get the keywords from the local storage, and then query the list of houses from the Firebase Realtime Database service, the Firebase service should return the list of houses that the address of each house should equaled to the keywords. After getting the houses, the search result component will pass them to the Houses component. The Houses component will be discussed in the following section.Please create the “SearchResults.js” file inside the “search” folder. The full source code can be found here.
As mentioned above, the Home component will get the list of houses from the Firebase Realtime Database service, and then pass the response to the Houses component via props. For this reason, the Houses component will be used to render the houses in the application. Each item in the list will be rendered by using the House component. We will talk about the House component in the following section. Please create the “houses” folder inside the “components” folder, and create the “Houses.js” file inside it. The full source code can be found here.
Each house in the list will be rendered by using the House component, in the Houses component, we will display the list of houses by using the map function, and then pass each item to the House component via props. Please create the “house.js” file inside the “houses” folder. The full source code can be found here.
After clicking on any item on the house list, the house information will be saved to the local storage. The house detail component will be shown. Inside the house detail component, we get the selected house information from the local storage and then display that information on the screen. On the other hand, the users can book the house, or they can chat with the host.
Please create the “detail” folder inside the “components” folder, and then create the “HouseDetail.js” file inside it. The full source code can be found here.
As we can see from the above code snippet, inside the house detail component, we use many other components, and they are house detail name component, house detail sub-component, house detail images component, house detail description component, house detail form component. All of them will be discussed here.
The house detail name component is used to display the name of the house. It will receive the house information as props. Please create the “HouseDetailName.js” file inside the “detail” folder. The full source code can be found here.
The house detail sub component is used to display the rating and the address of the house. It will receive the house information as props. Please create the “HouseDetailSub.js” file inside the “detail” folder. The full source code can be found here.
The house detail images component is used to display the images of the house. It will receive the house information as props. Please create the “HouseDetailImages.js” file inside the “detail” folder. The full source code can be found here.
The house detail description component is used to display the description of the house. It will receive the house information as props. Please create the “HouseDetailDescription.js” file inside the “detail” folder. The full source code can be found here.
The house detail form component is used to display the price and the rating of the house. On the other hand, it contains two buttons - the book button and the chat with host button. If the users click on the book button, they can book the house. Following that, if the users click on the chat with host button, they can chat with the owner of the house. It will receive the house information as props. Please create the “HouseDetailForm.js” file inside the “detail” folder. The full source code can be found here.
As mentioned in the above image, we can view the profile by clicking on the greeting of the header. The profile information will be saved to the local storage, and the profile component will get that information from the local storage. Please create the “profile” folder inside the “components” folder, and create the “Profile.js” file inside it. The full source code can be found here.
As we can see from the above code snippet, the Profile component uses many other components to display the information on the screen, and they are the profile left component, the profile intro component, the profile houses component. All of them will be discussed here.
The profile left component is used to display the user’s avatar, the badges, and some verified information. Please create the “ProfileLeft.js” file inside the “profile” component. The full source code can be found here.
The profile intro component is used to display the introduction of the user as you can see from the above image. Please create the “ProfileIntro.js” file inside the “profile” folder. The full source code can be found here.
We need to display the list of houses that were created by the authenticated user. The houses component will take the responsibility to do that. It will interact with the Firebase Realtime Database service to get the houses of the authenticated user. After that, it will show the response by using the map function, each house will be passed to the profile house component for displaying. The profile house component will be discusses in the following section. Please create the “ProfileHouses.js” file inside the “profile” folder. The full source code can be found here.
As mentioned above, each house will be rendered by using the profile house component. The profile house component will accept the house information as props. Please create the “ProfileHouse.js” file inside the “profile” folder. The full source code can be found here.
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 CometChatUI 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.
On the house detail page, the users can click on the “Chat with Host” button. After clicking on that button, the users will be redirected to the chat with host page. The host here is the person who uploaded the house for renting. In this ChatWithHost component, we use the CometChatMessages from the CometChat UI Kit and pass the seller id to the chatWithUser prop. Please create the “ChatWithHost.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 Airbnb clone by leveraging React.js, Firebase, CometChat SDK, and React UI Kit. You’ve been introduced to the chemistry behind Airbnb and how the CometChat SDK makes the Airbnb 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.