This content originally appeared on DEV Community and was authored by Hiep Le
Course Content
Table of Contents
No. | Topics |
---|---|
1 | About Code Courses |
2 | Live Demo |
3 | Setting Up CometChat |
4 | Setting Up CSS |
5 | Installing the App Dependencies |
6 | Setting Up Mapbox |
7 | Creating the .Env File |
8 | Conclusion |
1. About Code Courses
Code Courses is a website where people learn about coding and different technologies/frameworks/libraries. To help people learn, all of the courses are FREE and DETAIL. Hopefully, after following the content on Code Courses, you will find your dream jobs, and build any applications that you want.
2. Live Demo
After we finish this course, the final output will be like this:
If you want to find the full source code, you can refer to this Github link.
3. Setting Up CometChat
In this section, we will know how to set up CometChat in our application. Before doing that, we need to understand why we use the CometChat services to build the Uber clone application.
In fact, CometChat provides many services and UI Kits that help us build the chat, and voice/video calling features with minimal effort.
In order to set up CometChat, please follow the below steps:
- Step 1: Firstly, we need to go to the CometChat Dashboard and create an account.
- Step 2: After that, we need to log in to the CometChat dashboard.
-
Step 3: Following that, from the Dashboard, we add a new app called
uber-clone
.
- Step 4: Afterwards, we select this newly added app from the list.
-
Step 5: On the other hand, from the
Quick Start
option, we copy theAPP_ID
,REGION
, andAUTH_KEY
, which will be used later.
-
Step 6:: Please go to the
API & Auth Keys
section, and then copy theRest API Key
that will be used later.
- Step 7: At this step, we navigate to the Users tab, and delete all the default users (very important).
- Step 8: Last but not least, we navigate to the Groups tab and delete all the default groups (very important).
4. Setting Up CSS
In fact, we need to make our UI attractive. Therefore, in this section, we will set up CSS for our application. Hence, we do not need to care about styling because CSS was pre-prepared. Actually, the main reason behind this is that we want to focus on React.js, Firebase, and CometChat.
In the index.js
file, we are importing the index.css
file. This file contains all CSS for the application. We have different ways to set up styling for a React application, we can use the styled-components
library, or we can use the TailwindCSS
library, and so on.
However, as mentioned above, we want to focus on React.js, Firebase, and CometChat. Therefore, we will write all CSS in the index.css
file.
Please replace the current content of the index.css
file with the following content:
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
}
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
input {
outline: none;
border: none;
}
::-webkit-scrollbar {
display: none;
}
.login__container {
background-color: #f0f2f5;
display: grid;
grid-template-columns: 55% 45%;
height: 100vh;
width: 100vw;
}
.login__logo {
width: 10.25rem;
padding-left: 2.125rem;
}
.login__logo img {
width: 10.25rem !important;
}
.login__welcome {
padding-left: 10.5rem;
padding-top: 13.5rem;
}
.login__welcome img {
width: 18.75rem;
}
.mt-18 {
margin-top: -1.125rem;
}
.login__welcome p {
font-size: 1.5rem;
padding-left: 2.125rem;
}
.login__form-container {
padding-top: 6.5rem;
}
.login__form {
background-color: #fff;
box-shadow: 0 2px 4px rgb(0 0 0 / 10%), 0 8px 16px rgb(0 0 0 / 10%);
padding: 1.25rem;
width: 24.75rem;
}
.login__form input {
border: 1px solid #e5e7eb;
font-size: 1rem;
margin-bottom: 0.75rem;
padding: 0.875rem 1rem;
width: 100%;
}
.login__submit-btn {
background-color: #000000;
border: 0;
color: #fff;
font-size: 1rem;
font-weight: 600;
outline: none;
padding: 0.875rem 1rem;
width: 100%;
}
.login__submit-btn:hover {
cursor: pointer;
opacity: 0.8;
}
.login__forgot-password {
border-bottom: 1px solid #e5e7eb;
color: #000000;
display: block;
font-size: 0.9375rem;
padding: 1.25rem 0;
text-align: center;
}
.login__forgot-password:hover {
cursor: pointer;
}
.login__signup {
color: #000000;
display: block;
font-size: 0.9375rem;
padding: 1.25rem 0;
text-align: center;
}
.login__signup:hover {
cursor: pointer;
opacity: 0.8;
}
.loading {
background-color: rgba(255, 255, 255, 0.8);
display: block; /* Hidden by default */
height: 100%; /* Full height */
left: 0;
/* overflow: auto; */
position: fixed; /* Stay in place */
top: 0;
width: 100%; /* Full width */
z-index: 1000; /* Sit on top */
}
.lds-roller {
display: inline-block;
height: 5rem;
left: 48%;
position: fixed;
top: 50%;
width: 5rem;
z-index: 100;
}
.lds-roller div {
animation: lds-roller 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
transform-origin: 40px 40px;
}
.lds-roller div:after {
content: " ";
display: block;
position: absolute;
width: 7px;
height: 7px;
border-radius: 50%;
background: #000000;
margin: -4px 0 0 -4px;
}
.lds-roller div:nth-child(1) {
animation-delay: -0.036s;
}
.lds-roller div:nth-child(1):after {
top: 63px;
left: 63px;
}
.lds-roller div:nth-child(2) {
animation-delay: -0.072s;
}
.lds-roller div:nth-child(2):after {
top: 68px;
left: 56px;
}
.lds-roller div:nth-child(3) {
animation-delay: -0.108s;
}
.lds-roller div:nth-child(3):after {
top: 71px;
left: 48px;
}
.lds-roller div:nth-child(4) {
animation-delay: -0.144s;
}
.lds-roller div:nth-child(4):after {
top: 72px;
left: 40px;
}
.lds-roller div:nth-child(5) {
animation-delay: -0.18s;
}
.lds-roller div:nth-child(5):after {
top: 71px;
left: 32px;
}
.lds-roller div:nth-child(6) {
animation-delay: -0.216s;
}
.lds-roller div:nth-child(6):after {
top: 68px;
left: 24px;
}
.lds-roller div:nth-child(7) {
animation-delay: -0.252s;
}
.lds-roller div:nth-child(7):after {
top: 63px;
left: 17px;
}
.lds-roller div:nth-child(8) {
animation-delay: -0.288s;
}
.lds-roller div:nth-child(8):after {
top: 56px;
left: 12px;
}
@keyframes lds-roller {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/* The Modal (background) */
.signup {
background-color: rgba(255, 255, 255, 0.8);
display: block; /* Hidden by default */
height: 100%; /* Full height */
left: 0;
/* overflow: auto; */
position: fixed; /* Stay in place */
top: 0;
width: 100%; /* Full width */
z-index: 1; /* Sit on top */
}
/* Modal Content/Box */
.signup__content {
background-color: #fefefe;
box-shadow: 0 2px 4px rgb(0 0 0 / 10%), 0 8px 16px rgb(0 0 0 / 10%);
margin: 0% auto; /* 15% from the top and centered */
/* margin-top: 10%; */
width: 27rem; /* Could be more or less, depending on screen size */
}
.signup__container {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
.signup__title {
font-size: 1.25rem;
font-weight: 600;
padding: 1.25rem 0 0.5rem 1.25rem;
}
.signup__close {
align-items: center;
display: grid;
justify-items: right;
padding: 1.25rem 1.25rem 0.5rem 0;
}
.signup__close img:hover {
cursor: pointer;
}
.signup__subtitle {
background: #e5e7eb;
height: 1px;
margin-bottom: 0.5rem;
width: 100%;
}
.signup__form {
width: 100%;
padding: 1.25rem;
}
.signup__user-avatar {
padding-bottom: 0.5rem;
text-align: center;
}
.signup__about {
background-color: #f3f4f6;
border: 1px solid #e5e7eb;
font-family: inherit;
font-size: 0.9375rem;
height: 3.5rem;
padding: 0.75rem;
width: 100%;
}
.signup__user-avatar img {
border-radius: 0.5rem;
height: 6rem;
object-fit: cover;
width: 6rem;
}
.signup__user-avatar img:hover {
cursor: pointer;
}
.signup__upload-container {
background-color: #f3f4f6;
border: 1px solid #e5e7eb;
display: block;
font-size: 0.9375rem;
margin-bottom: 0.75rem;
padding: 0.875rem 1rem;
width: 100%;
}
.signup__upload-container:hover {
cursor: pointer;
}
.signup__upload-avatar {
display: none !important;
}
.signup__form input {
background-color: #f3f4f6;
border: 1px solid #e5e7eb;
display: block;
font-size: 0.9375rem;
margin-bottom: 0.75rem;
padding: 0.875rem 1rem;
width: 100%;
}
.signup__form select {
background-color: #f3f4f6;
border: 1px solid #e5e7eb;
display: block;
font-size: 0.9375rem;
height: 2.625rem;
margin-bottom: 0.75rem;
outline: none;
padding: 0 1rem;
width: 100%;
}
.signup__btn {
background-color: #000000;
border: 0;
color: #fff;
display: block;
font-size: 1rem;
font-weight: 600;
margin: 1.25rem auto;
outline: none;
padding: 0.875rem 1rem;
}
.signup__btn:hover {
cursor: pointer;
opacity: 0.8;
}
.header {
background: #000000;
display: grid;
grid-template-columns: repeat(2, 1fr);
height: 3.5rem;
left: 0;
position: fixed;
right: 0;
top: 0;
width: 100%;
z-index: 99999;
}
.header__left {
align-items: center;
display: grid;
grid-gap: 1rem;
grid-template-columns: max-content max-content;
padding-left: 0.75rem;
}
.header__left span {
color: #fff;
font-weight: bold;
}
.header__left img {
width: 3.25rem;
}
.header__right {
align-items: center;
color: white;
display: grid;
grid-gap: 0.75rem;
grid-template-columns: max-content max-content max-content;
justify-content: right;
padding-right: 0.75rem;
}
.header__logout {
align-items: center;
color: #fff;
display: grid;
justify-content: right;
padding-right: 0.75rem;
}
.header__right img {
border-radius: 50%;
height: 2rem;
object-fit: cover;
width: 2rem;
}
.header__logout span:hover {
cursor: pointer;
opacity: 0.8;
}
.address {
background-color: rgb(255, 255, 255);
box-shadow: rgb(0 0 0 / 15%) 0px 4px 16px;
height: 32.0625rem;
left: 2%;
position: fixed;
top: 13%;
width: 25rem;
z-index: 999;
}
.address__title {
align-items: center;
background-color: #2563eb;
color: #fff;
display: grid;
font-size: 1rem;
height: 11.875rem;
}
.address__title-container {
padding-left: 0.75rem;
position: relative;
}
.address__title-container p {
position: relative;
padding-left: 1.25rem;
}
.address__title-container p:hover {
cursor: pointer;
}
.address__title-from::before {
content: "";
width: 8px;
height: 8px;
background: white;
position: absolute;
top: 43%;
border-radius: 50%;
left: 0%;
}
.address__title-to {
padding-top: 1rem;
}
.address__title-to::before {
content: "";
width: 8px;
height: 8px;
background: white;
position: absolute;
top: 62%;
border-radius: 50%;
left: 0%;
}
.search {
padding: 0.75rem;
}
.search__input {
background: #f3f4f6;
border: 1px solid #e5e7eb;
font-size: 1rem;
margin-bottom: 0.75rem;
padding: 0.875rem 1rem;
width: 100%;
border-bottom: 2px solid #2563eb;
}
.leaflet-routing-container {
display: none;
}
.pin {
position: absolute;
top: 40%;
left: 50%;
margin-left: -115px;
border-radius: 50% 50% 50% 0;
border: 4px solid red;
width: 20px;
height: 20px;
transform: rotate(-45deg);
}
.pin::after {
position: absolute;
content: "";
width: 5px;
height: 5px;
border-radius: 50%;
top: 50%;
left: 50%;
margin-left: -3px;
margin-top: -3px;
background-color: red;
}
.leaflet-default-icon-path {
background-image: url(https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon.png);
}
.search__result {
max-height: 250px;
overflow-y: auto;
}
.search__result-item {
border-bottom: 1px solid #ccc;
display: grid;
grid-gap: 1rem;
grid-template-columns: max-content auto;
padding: 0.75rem 0;
padding-left: 0.5rem;
}
.search__result-item:hover {
cursor: pointer;
background: #f3f4f6;
}
.search__result-icon {
align-items: center;
background: #ccc;
border-radius: 50%;
display: grid;
height: 1.5rem;
justify-content: center;
width: 1.5rem;
}
.search__result-icon svg {
fill: #fff;
height: 0.75rem;
width: 0.75rem;
}
/* The Modal (background) */
.request-ride {
background-color: rgba(255, 255, 255, 0.8);
display: block; /* Hidden by default */
height: 100%; /* Full height */
left: 0;
/* overflow: auto; */
position: fixed; /* Stay in place */
top: 0;
width: 100%; /* Full width */
z-index: 1000; /* Sit on top */
}
/* Modal Content/Box */
.request-ride__content {
background-color: #fefefe;
box-shadow: 0 2px 4px rgb(0 0 0 / 10%), 0 8px 16px rgb(0 0 0 / 10%);
margin: 15% auto; /* 15% from the top and centered */
margin-top: 13%;
width: 27rem; /* Could be more or less, depending on screen size */
}
.request-ride__container {
display: grid;
grid-template-columns: repeat(2, 1fr);
}
.request-ride__title {
font-size: 1.25rem;
font-weight: 600;
padding: 1.25rem 0 0.5rem 1.25rem;
}
.request-ride__close {
align-items: center;
display: grid;
justify-items: right;
padding: 1.25rem 1.25rem 0.5rem 0;
}
.request-ride__close img:hover {
cursor: pointer;
}
.request-ride__subtitle {
background: #e5e7eb;
height: 1px;
margin-bottom: 0.5rem;
width: 100%;
}
.request-ride__form {
width: 100%;
padding: 1.25rem;
}
.request-ride__btn {
background-color: #000000;
border: 0;
color: #fff;
font-size: 1rem;
font-weight: 600;
margin: 1.25rem auto;
outline: none;
padding: 0.875rem 1rem;
}
.request-ride__btn:hover {
cursor: pointer;
opacity: 0.8;
}
.request-ride__change-btn {
background-color: transparent;
color: #000;
}
.ride-list {
background-color: rgb(255, 255, 255);
box-shadow: rgb(0 0 0 / 15%) 0px 4px 16px;
height: 32.0625rem;
left: 2%;
position: fixed;
top: 13%;
width: 25rem;
z-index: 999;
}
.ride-list__container {
border-bottom: 1px solid #ccc;
display: grid;
grid-template-columns: repeat(2, 1fr);
}
.ride-list__title {
font-size: 1.25rem;
font-weight: 600;
padding: 1.25rem 0 1.25rem 1.25rem;
}
.search__result {
max-height: 250px;
overflow-y: auto;
}
.ride-list__content {
max-height: 100%;
overflow-y: auto;
}
.ride-list__result-item {
border-bottom: 1px solid #ccc;
display: grid;
grid-gap: 1rem;
grid-template-columns: max-content auto;
padding: 0.75rem 0;
padding-left: 0.5rem;
}
.ride-list__result-item:hover {
cursor: pointer;
background: #f3f4f6;
}
.ride-list__result-icon {
align-items: center;
background: #ccc;
border-radius: 50%;
display: grid;
height: 1.5rem;
justify-content: center;
width: 1.5rem;
}
.ride-list__result-icon svg {
fill: #fff;
height: 0.75rem;
width: 0.75rem;
}
.ride-list__result-label {
font-size: 0.9375rem;
padding-bottom: 0.5rem;
}
.ride-list__result-label span {
color: #000;
font-weight: 600;
}
.ride-list__accept-btn {
background: #000;
border: none;
color: #fff;
font-size: 0.9375rem;
outline: none;
padding: 0.5rem 1rem;
}
.ride-list__accept-btn:hover {
cursor: pointer;
opacity: 0.8;
}
.empty-message {
padding: 0.75rem;
}
.ride-detail {
background-color: rgb(255, 255, 255);
box-shadow: rgb(0 0 0 / 15%) 0px 4px 16px;
height: 32.0625rem;
left: 2%;
position: fixed;
top: 13%;
width: 25rem;
z-index: 999;
}
.ride-detail__user-avatar {
display: grid;
justify-content: center;
padding-bottom: 1rem;
padding-top: 2rem;
}
.ride-detail__user-avatar img {
border-radius: 50%;
height: 5rem;
object-fit: cover;
width: 5rem;
}
.ride-detail__user-info {
color: #000;
font-weight: 600;
text-align: center;
}
.ride-detail__btn {
background: #000;
border: none;
color: #fff;
font-size: 0.9375rem;
margin: 0.25rem 0;
outline: none;
padding: 0.75rem 1rem;
width: 100%;
}
.ride-detail__btn:hover {
cursor: pointer;
opacity: 0.8;
}
.ride-detail__result-label {
font-size: 0.9375rem;
line-height: 2rem;
padding-bottom: 0.5rem;
}
.ride-detail__result-label span {
color: #000;
font-weight: 600;
}
.ride-detail__actions {
align-items: center;
display: flex;
gap: 1rem;
justify-content: center;
padding: 0 2rem 1rem 2rem;
}
.ride-detail__action {
align-items: center;
border-radius: 50%;
border: 1px solid #000;
display: flex;
height: 2.5rem;
justify-content: center;
width: 2.5rem;
}
.ride-detail__action:hover {
cursor: pointer;
opacity: 0.8;
}
.ride-detail__action img {
border-radius: 50%;
height: 1.25rem;
width: 1.25rem;
}
.ride-detail__content {
padding: 0 2rem;
}
.shown {
display: block !important;
}
.hidden {
display: none !important;
}
5. Installing the App Dependencies
In this section, we will set up dependencies for our application. Because in this app, we need to interact with Firebase, CometChat or we need to validate the input fields or we need to navigate between pages. For this reason, we will install some useful libraries that will help us achieve those things.
In order to install a new package/library in a React application, we need to follow the below steps:
-
Step 1: Firstly, we open the terminal and
cd
to the project directory. If you've done that, you can ignore this step.
To install a package, we need to run the following statement:
npm i package_name
package_name: is the library name that we want to install.
By applying the above steps, we will install the dependencies for our application. Here is the list of dependencies that needs to be installed.
-
firebase
: we need to interact with the Firebase services. Therefore, we need to install thefirebase
library.
cd
to your project folder and run the following statement.
npm install firebase@8.9.1
Note: at the time of writing this tutorial, we use the firebase library and its version is 8.9.1.
-
uuid
: while developing the application, we will need to generate the unique id for the objects such as the users, etc. theuuid
will help us to generate unique ids.
cd
to your project folder and run the following statement.
npm install uuid
-
validator
: in this course, we will have thelogin
andregister
features. It means that we need to deal with the input elements. Hence, we need to develop the validation. thevalidator
library helps us to validate the input elements such as email, phone number, required fields, etc.
cd
to your project folder and run the following statement.
npm install validator
-
react-router-dom
: we need to navigate between pages, our application contains different routes. For example, after the users have logged in to the application, they will be redirected to the home page, or after the users have clicked on the logout button, they will be redirected to the login page, etc. Thereact-router-dom
library is a powerful library that will help us navigate between pages.
cd
to your project folder and run the following statement.
npm install react-router-dom@5.2.0
Note: at the time of writing this course, we use the react-router-dom library and its version is 5.2.0.
-
leaflet
: According to the below image, we want to display a map. We will use theleaftlet
library to achieve that.
cd
to your project folder and run the following statement.
npm install leaflet@1.7.1
Note: at the time of writing this course, we use the leaflet library and its version is 1.7.1.
-
leaflet-routing-machine
: According to the below image, we want to draw a route on our map. We will use theleaflet-routing-machine
library to achieve that.
cd
to your project folder and run the following statement.
npm install leaflet-routing-machine@3.2.12
Note: at the time of writing this course, we use the leaflet-routing-machine library and its version is 3.2.12.
-
leaflet-geosearch
: As we can see from the below image, the users can search locations. We will use theleaflet-geosearch
library to achieve that.
cd
to your project folder and run the following statement.
npm install leaflet-geosearch@3.5.0
Note: at the time of writing this course, we use the leaflet-geosearch library and its version is 3.5.0.
6. Setting Up Maxbox
In this project, we need to use the leaflet-routing-machine library to draw a route between two locations. However, the default OSRM server sometimes appears down. For this reason, we need another alternative solution. In this project, we will use Mapbox as an OSRM service. To setup Mapbox, you need to follow the below steps:
- Step 1: Please go to this page to create a new Mapbox account.
- Step 2: After creating a new Mapbox account, we need to login to the Mapbox platform by going to this link.
-
Step 3: After logging into the Mapbox platform, we will be redirected to the page where you can get the
Access Token
.
Note: We need to copy the
Access Token
. It will be used in the next section.
Congratulation! we have set up Mapbox for our Uber clone. In the next section, we will set up the .env
file.
7. Creating the .Env File
In this part, we will set up the .env
file. Instead of hard-coding the credentials in our code, the best practice is that we need to store those credentials in the .env
file. Those credentials can be accessed as environment variables.
To create the .env
file, please follow the below steps:
-
Step 1: Create the
.env
file in the project root directory.
-
Step 2: Replace the content of the
.env
file with the following content
REACT_APP_FIREBASE_API_KEY = xxx - xxx - xxx - xxx - xxx - xxx - xxx - xxx
REACT_APP_FIREBASE_AUTH_DOMAIN = xxx - xxx - xxx - xxx - xxx - xxx - xxx - xxx
REACT_APP_FIREBASE_DATABASE_URL = xxx - xxx - xxx - xxx - xxx - xxx - xxx - xxx
REACT_APP_FIREBASE_STORAGE_BUCKET =
xxx - xxx - xxx - xxx - xxx - xxx - xxx - xxx
REACT_APP_COMETCHAT_APP_ID = xxx - xxx - xxx - xxx - xxx - xxx - xxx - xxx
REACT_APP_COMETCHAT_REGION = xxx - xxx - xxx - xxx - xxx - xxx - xxx - xxx
REACT_APP_COMETCHAT_AUTH_KEY = xxx - xxx - xxx - xxx - xxx - xxx - xxx - xxx
REACT_APP_COMETCHAT_API_KEY = xxx - xxx - xxx - xxx - xxx - xxx - xxx - xxx
REACT_APP_MAP_BOX_API_KEY = xxx - xxx - xxx - xxx - xxx - xxx - xxx - xxx
-
Step 3: Replace the
xxx - xxx - xxx - xxx - xxx - xxx - xxx - xxx
with the corresponding credentials.
REACT_APP_FIREBASE_API_KEY
: Your Firebase API Key.
REACT_APP_FIREBASE_AUTH_DOMAIN
: Your Firebase Auth Domain.
REACT_APP_FIREBASE_DATABASE_URL
: Your Firebase Database Url.
REACT_APP_FIREBASE_STORAGE_BUCKET
: Your Firebase Storage Bucket.
REACT_APP_COMETCHAT_APP_ID
: Your CometChat App ID.
REACT_APP_COMETCHAT_REGION
: Your CometChat Region.
REACT_APP_COMETCHAT_AUTH_KEY
: Your CometChat Auth Key.
REACT_APP_COMETCHAT_API_KEY
: Your CometChat API Key.
REACT_APP_MAP_BOX_API_KEY
: Your Mapbox API Key.
-
Step 4: We need to create a file which is called the
firebase.js
file to interact with the Firebase services, it will read the env variables from the.env
file. Please create thefirebase.js
file in thesrc
folder.
Here is the content of the firebase.js
file:
import firebase from "firebase";
import "firebase/storage";
const firebaseConfig = {
apiKey: `${process.env.REACT_APP_FIREBASE_API_KEY}`,
authDomain: `${process.env.REACT_APP_FIREBASE_AUTH_DOMAIN}`,
databaseURL: `${process.env.REACT_APP_FIREBASE_DATABASE_URL}`,
projectId: `${process.env.REACT_APP_FIREBASE_PROJECT_ID}`,
storageBucket: `${process.env.REACT_APP_FIREBASE_STORAGE_BUCKET}`,
messagingSenderId: `${process.env.REACT_APP_FIREABSE_MESSAGING_SENDER_ID}`,
appId: `${process.env.REACT_APP_FIREBASE_APP_ID}`,
};
const app = !firebase.apps.length
? firebase.initializeApp(firebaseConfig)
: firebase.app();
const realTimeDb = app.database();
const auth = app.auth();
const storage = firebase.storage();
export { auth, storage, realTimeDb };
In this project, we need to interact with some Firebase services, and they are the Firebase Realtime Database, the Firebase Authentication, and the Firebase Storage.
8. Conclusion
Congratulation! We have finished the second part of the How to Build Uber Clone with React
course. In conclusion, we have set up CometChat, CSS, the App dependencies, Mapbox, and the .env
file. Please continue with the next part of this series.
This content originally appeared on DEV Community and was authored by Hiep Le

Hiep Le | Sciencx (2022-07-15T17:16:38+00:00) How to Build Uber Clone with React (Ep. 2) [FREE & DETAIL COURSE]. Retrieved from https://www.scien.cx/2022/07/15/how-to-build-uber-clone-with-react-ep-2-free-detail-course/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.