Build a secure feature-complete chat app with React & Firebase in 7 minutes. Try it out 👉 https://fireship-demos.web.app/

Source Code: https://github.com/fireship-io/react-firebase-chat
ReactFire Game Lobby by Jarrett Helton:  https://fireship.io/lessons/game-lobby-with-firebase-reactfire/

#react #js #firebase

Install the quiz app 🤓

iOS https://itunes.apple.com/us/app/fireship/id1462592372?mt=8
Android https://play.google.com/store/apps/details?id=io.fireship.quizapp

Upgrade to Fireship PRO at https://fireship.io/pro
Use code lORhwXd2 for 25% off your first payment. 

My VS Code Theme

- Atom One Dark 
- vscode-icons
- Fira Code Font
2024-02-04T06:05:58.057Z
nova-2
2-general-nova
2024-01-09.29447
30089e05-99d1-4376-b32e-c263170674af
065fe360-c4fd-47ab-a6ec-619871b94a53
a83901cfccb6a152307f91ad1cf52877aa64278f22dadf83d672bf76f91c3700
67875a7f-c9c4-48a0-aa55-5bdb8a91c34a
deprecated
Once upon a time, building a real time chat app required a lot of carefully engineered code.
Today, when you combine tools like React and Firebase, you can build a basic chat app from scratch in under 7 minutes.
The app you'll build today is live on the Internet, so feel free to check it out.
Now I already know what most of you are thinking.
You'll go into the live demo, say some terrible things, and try to break the app by spamming it with a ton of messages.
But we can get a lot done in 7 minutes.
There's plenty of time to implement security logic, and we'll even write some back end code to ban a user for life if they violate our community guidelines.
But most importantly, you'll learn how to to get users with Firebase and how to work with real time data in Firestore using React Hooks.
If you're new here, like and subscribe, and you can reference the code on GitHub.
And if you wanna go beyond the basics, check out this React Fire article by Jarrett Helton on Fireship IO.
Before we get started, let's quickly take a look at what we're building today.
It's a single group chat room that everybody can participate in, kind of like super chat on YouTube.
To enter the chat, a user must log in with their Google account.
Once logged in, they can post messages into the chat, each message is a document in the Firestore database.
It contains the text, user ID, and time stamp for that message.
We make a query to the database for the most recent messages.
Is whenever the underlying data changes on the back end, the React app will update with the most recent messages on the front end.
It's very easy to implement, and by the end of this video, you'll have a great starting point for building really any type of real time application.
Let's go ahead and get started.
Open up the terminal, and then I'll set a timer for 7 minutes.
Run npx create React app to create an initial React project.
Run code followed by the name of your app to open it in Versus Code.
We have 2 extra dependencies to install, Firebase, and React Firebase Hooks.
Once installed, we can open up the app JS file, which is where we'll write all of our front end code.
Go ahead and delete the boilerplate code except for the app and the header.
First, we'll import the Firebase SDK along with Firestore for our database and auth for user authentication.
Then we'll import a couple of hooks here to make it easier to work with Firebase and React.
We'll call Firebase initialize app to identify a project, and then we'll make a reference to the auth and Firestore SDKs as global variables.
But we don't have a Firebase project yet, so let's create one by clicking add project from the Firebase site.
Once we get to the console, we can then tweak a couple of settings.
To allow users to sign in with their Google account, we'll go to the authentication tab and enable Google sign in.
From there, we'll go to the Cloud Firestore tab and enable the database.
The last thing we'll do is click on the gear and then add a new web app to our project.
When you do that, it will give you a JavaScript object that identifies your project.
Go ahead and copy those values and paste them into the Firebase initialize app in your source code.
And now that we have Firebase set up, we need to architect this app.
Here we have our main app component.
If a user is signed in, we'll show the chat room.
Otherwise, we'll show a button to sign in with Google.
Knowing whether or not a user is logged in is dead simple with the use auth state hook.
If a user is logged in, it returns an object that has a user ID, email address, and other info.
When logged out, the user object is null.
That means if we create additional components for sign in and chat room, we can then use a simple ternary operator to say, if the user is defined, show the chat room.
Otherwise, show the sign in component.
And now the question becomes, how do we sign in?
In our sign in component, we'll return a button that listens to the click event and runs a function called sign in with Google.
Inside that function, we instantiate a provider called the Google auth provider, then we pass it to the sign in with pop up method, which will trigger this pop up window when the user clicks on the button.
It wouldn't hurt to add a sign out button as well.
And in that component, we'll check to see if we have a current user, in which case we return a button that triggers the sign out method.
And now we're ready to build our chat room.
In Firestore, we have a collection of messages.
When a user adds a new message to the chat, it creates a document in this collection along with a time stamp and their user ID.
In our code, we make a reference to this point in the database by calling Firestore collection.
We can then make a query for a subset of documents, which we want ordered by the created at timestamp and limited to a maximum of 25, we can then make this query and listen to any updates to the data in real time with the use collection data hook.
It returns an array of objects where each object is the chat message in the database.
And, again, anytime the data changes, React will rerender with the latest data.
In the template, we can map over the array of messages.
And for each message, we'll use a dedicated chat message component that has a key prop with the message ID and passes the document data as the message prop, we can then go and define the chat message child component, then we can show the actual text by accessing it from the props message.
At this point, if you open up the Firestore console and add a new document to the messages collection, it should magically appear in your React UI and respond to any updates.
Just make sure it has a text and created at field.
Now when we display chat messages, we want to distinguish between messages that were sent and received.
We can do that by comparing the user ID on the Firestore document to the currently logged in user.
If they're equal, then we know the current user sent the message.
We can then apply different styling based on whether or not the message was sent or received.
You might also want to add a photo URL here as well.
Okay.
So now we need to wait in the UI for the user to send a message.
We can start that feature off by adding a form below our messages list.
Inside that form, we have a single input and then a button to submit the message, what we wanna do from there is add a stateful value to our component called form value.
We can do that with the use state hook and have it start as an empty string.
We can then go down to the input itself and bind its value to the form value state.
Then whenever the user types into the form, it triggers the change event.
So we'll listen to the on change event, then we'll take the value of the change and set it as the form value state.
That takes care of the value the user types in the form, but now we need a way to submit it to write to the database.
When the user clicks the button or submits the form, we can listen to the on submit event on the form itself and then we'll trigger an event handler called send a message.
We'll define this as an async function in our component that takes the event as its argument.
Normally, when a form is submitted, it will refresh the page.
But we can call prevent default to stop that from happening.
From there, we'll grab the user ID from the currently logged in user.
Then we call await messages ref add, which will write a new document to the database.
It takes a JavaScript object as its argument with the values that you want to write to the database.
The text will be our form value.
We'll give it a created at time stamp on the server and, of course, the user ID.
That'll resolve when the document is created, and then we can reset our form value back to an empty string.
And you should now be able to send messages in the chat and see them updated in the database.
Now at this point, the main problem is that our app looks terrible.
And the way we'll fix that is by going to the source code and copying the CSS from there.
The reality is that CSS is way harder than React or Firebase and we're getting kind of short on time, we have some bigger problems to address with this app.
First of all, when we enter a chat message, it doesn't automatically scroll to the bottom, which is kind of annoying.
The way we can fix that is by adding an empty div below our list of chat messages.
We can then reference that element with the ref prop and then connect it to our code with the use ref hook.
Now that we have a reference to this element, we can go back into the send message function and we'll call scroll into view whenever the user sends a message.
And we now have a feature complete production ready UI without any bugs whatsoever.
Now we can shift gears into the back end with our most important concern being security.
In Firestore, you can use a JavaScript script like syntax to write security rules that you would otherwise have to implement on a back end server, we can modify our rules in the Firebase console.
We'll first match the path to the messages collection in the database.
When a user wants to read a document, we wanna make sure that they're logged into their account.
We can apply that logic by checking if the request auth user ID does not equal null, and it's just that simple.
When it comes to creating a document, there are some additional things to think about.
We wanna make sure a user is signed in, that they can only create documents with their own user ID, and that they're not banned for whatever reason.
We can extract this logic into a custom function called can create message.
We'll make sure they're logged in.
We'll make sure that the user ID matches the user ID on the document they're trying to create.
I can also read other documents in the database.
I have a banned collection for evil users.
And if your user ID is in it, then you can't write to the database.
Go ahead and click save, and we now have a fully secure app without any vulnerabilities whatsoever.
We still have about a minute left, so let's go ahead and implement some back end code to filter out bad words and then ban users who violate the community guidelines, you can set up a serverless back end server by running Firebase init functions from the command line.
That creates a node project in the functions directory.
It can CD into it, and then we'll install the bad words package.
From there, we can export a Cloud function that runs every time a new document is created in the messages collection, that'll give us access to the message text, which we can then check for profanity.
If there is profanity, then we'll clean the text and then ban the user for life, when we're done, we can deploy the function by running Firebase deploy only functions.
Congratulations.
You just built a full stack chat app with React and Firebase.
It's secure, flexible, scales infinitely in the cloud, and like any good social app, it enforces community guidelines.
I'm gonna go ahead and wrap things up there.
If this video helped you, please like and subscribe.
And in the near future, I'll be working on a full React Firebase course.
It'll be available to pro members.
And if you have any ideas, please feel free to leave them in the comments or let me know on our Slack channel.
Thanks for watching and I will see you in the next one.

Speaker 0: Once upon a time, building a real time chat app required a lot of carefully engineered code. Today, when you combine tools like React and Firebase, you can build a basic chat app from scratch in under 7 minutes. The app you'll build today is live on the Internet, so feel free to check it out. Now I already know what most of you are thinking. You'll go into the live demo, say some terrible things, and try to break the app by spamming it with a ton of messages.

But we can get a lot done in 7 minutes. There's plenty of time to implement security logic, and we'll even write some back end code to ban a user for life if they violate our community guidelines. But most importantly, you'll learn how to to get users with Firebase and how to work with real time data in Firestore using React Hooks. If you're new here, like and subscribe, and you can reference the code on GitHub. And if you wanna go beyond the basics, check out this React Fire article by Jarrett Helton on Fireship IO.

Before we get started, let's quickly take a look at what we're building today. It's a single group chat room that everybody can participate in, kind of like super chat on YouTube. To enter the chat, a user must log in with their Google account. Once logged in, they can post messages into the chat, each message is a document in the Firestore database. It contains the text, user ID, and time stamp for that message.

We make a query to the database for the most recent messages. Is whenever the underlying data changes on the back end, the React app will update with the most recent messages on the front end. It's very easy to implement, and by the end of this video, you'll have a great starting point for building really any type of real time application. Let's go ahead and get started. Open up the terminal, and then I'll set a timer for 7 minutes.

Run npx create React app to create an initial React project. Run code followed by the name of your app to open it in Versus Code. We have 2 extra dependencies to install, Firebase, and React Firebase Hooks. Once installed, we can open up the app JS file, which is where we'll write all of our front end code. Go ahead and delete the boilerplate code except for the app and the header.

First, we'll import the Firebase SDK along with Firestore for our database and auth for user authentication. Then we'll import a couple of hooks here to make it easier to work with Firebase and React. We'll call Firebase initialize app to identify a project, and then we'll make a reference to the auth and Firestore SDKs as global variables. But we don't have a Firebase project yet, so let's create one by clicking add project from the Firebase site. Once we get to the console, we can then tweak a couple of settings.

To allow users to sign in with their Google account, we'll go to the authentication tab and enable Google sign in. From there, we'll go to the Cloud Firestore tab and enable the database. The last thing we'll do is click on the gear and then add a new web app to our project. When you do that, it will give you a JavaScript object that identifies your project. Go ahead and copy those values and paste them into the Firebase initialize app in your source code.

And now that we have Firebase set up, we need to architect this app. Here we have our main app component. If a user is signed in, we'll show the chat room. Otherwise, we'll show a button to sign in with Google. Knowing whether or not a user is logged in is dead simple with the use auth state hook.

If a user is logged in, it returns an object that has a user ID, email address, and other info. When logged out, the user object is null. That means if we create additional components for sign in and chat room, we can then use a simple ternary operator to say, if the user is defined, show the chat room. Otherwise, show the sign in component. And now the question becomes, how do we sign in?

In our sign in component, we'll return a button that listens to the click event and runs a function called sign in with Google. Inside that function, we instantiate a provider called the Google auth provider, then we pass it to the sign in with pop up method, which will trigger this pop up window when the user clicks on the button. It wouldn't hurt to add a sign out button as well. And in that component, we'll check to see if we have a current user, in which case we return a button that triggers the sign out method. And now we're ready to build our chat room.

In Firestore, we have a collection of messages. When a user adds a new message to the chat, it creates a document in this collection along with a time stamp and their user ID. In our code, we make a reference to this point in the database by calling Firestore collection. We can then make a query for a subset of documents, which we want ordered by the created at timestamp and limited to a maximum of 25, we can then make this query and listen to any updates to the data in real time with the use collection data hook. It returns an array of objects where each object is the chat message in the database.

And, again, anytime the data changes, React will rerender with the latest data. In the template, we can map over the array of messages. And for each message, we'll use a dedicated chat message component that has a key prop with the message ID and passes the document data as the message prop, we can then go and define the chat message child component, then we can show the actual text by accessing it from the props message. At this point, if you open up the Firestore console and add a new document to the messages collection, it should magically appear in your React UI and respond to any updates. Just make sure it has a text and created at field.

Now when we display chat messages, we want to distinguish between messages that were sent and received. We can do that by comparing the user ID on the Firestore document to the currently logged in user. If they're equal, then we know the current user sent the message. We can then apply different styling based on whether or not the message was sent or received. You might also want to add a photo URL here as well.

Okay. So now we need to wait in the UI for the user to send a message. We can start that feature off by adding a form below our messages list. Inside that form, we have a single input and then a button to submit the message, what we wanna do from there is add a stateful value to our component called form value. We can do that with the use state hook and have it start as an empty string.

We can then go down to the input itself and bind its value to the form value state. Then whenever the user types into the form, it triggers the change event. So we'll listen to the on change event, then we'll take the value of the change and set it as the form value state. That takes care of the value the user types in the form, but now we need a way to submit it to write to the database. When the user clicks the button or submits the form, we can listen to the on submit event on the form itself and then we'll trigger an event handler called send a message.

We'll define this as an async function in our component that takes the event as its argument. Normally, when a form is submitted, it will refresh the page. But we can call prevent default to stop that from happening. From there, we'll grab the user ID from the currently logged in user. Then we call await messages ref add, which will write a new document to the database.

It takes a JavaScript object as its argument with the values that you want to write to the database. The text will be our form value. We'll give it a created at time stamp on the server and, of course, the user ID. That'll resolve when the document is created, and then we can reset our form value back to an empty string. And you should now be able to send messages in the chat and see them updated in the database.

Now at this point, the main problem is that our app looks terrible. And the way we'll fix that is by going to the source code and copying the CSS from there. The reality is that CSS is way harder than React or Firebase and we're getting kind of short on time, we have some bigger problems to address with this app. First of all, when we enter a chat message, it doesn't automatically scroll to the bottom, which is kind of annoying. The way we can fix that is by adding an empty div below our list of chat messages.

We can then reference that element with the ref prop and then connect it to our code with the use ref hook. Now that we have a reference to this element, we can go back into the send message function and we'll call scroll into view whenever the user sends a message. And we now have a feature complete production ready UI without any bugs whatsoever. Now we can shift gears into the back end with our most important concern being security. In Firestore, you can use a JavaScript script like syntax to write security rules that you would otherwise have to implement on a back end server, we can modify our rules in the Firebase console.

We'll first match the path to the messages collection in the database. When a user wants to read a document, we wanna make sure that they're logged into their account. We can apply that logic by checking if the request auth user ID does not equal null, and it's just that simple. When it comes to creating a document, there are some additional things to think about. We wanna make sure a user is signed in, that they can only create documents with their own user ID, and that they're not banned for whatever reason.

We can extract this logic into a custom function called can create message. We'll make sure they're logged in. We'll make sure that the user ID matches the user ID on the document they're trying to create. I can also read other documents in the database. I have a banned collection for evil users.

And if your user ID is in it, then you can't write to the database. Go ahead and click save, and we now have a fully secure app without any vulnerabilities whatsoever. We still have about a minute left, so let's go ahead and implement some back end code to filter out bad words and then ban users who violate the community guidelines, you can set up a serverless back end server by running Firebase init functions from the command line. That creates a node project in the functions directory. It can CD into it, and then we'll install the bad words package.

From there, we can export a Cloud function that runs every time a new document is created in the messages collection, that'll give us access to the message text, which we can then check for profanity. If there is profanity, then we'll clean the text and then ban the user for life, when we're done, we can deploy the function by running Firebase deploy only functions. Congratulations. You just built a full stack chat app with React and Firebase. It's secure, flexible, scales infinitely in the cloud, and like any good social app, it enforces community guidelines.

I'm gonna go ahead and wrap things up there. If this video helped you, please like and subscribe. And in the near future, I'll be working on a full React Firebase course. It'll be available to pro members. And if you have any ideas, please feel free to leave them in the comments or let me know on our Slack channel.

Thanks for watching and I will see you in the next one.
Once upon a time, building a real time chat app required a lot of carefully engineered code. Today, when you combine tools like React and Firebase, you can build a basic chat app from scratch in under 7 minutes. The app you'll build today is live on the Internet, so feel free to check it out. Now I already know what most of you are thinking.
You'll go into the live demo, say some terrible things, and try to break the app by spamming it with a ton of messages. But we can get a lot done in 7 minutes. There's plenty of time to implement security logic, and we'll even write some back end code to ban a user for life if they violate our community guidelines. But most importantly, you'll learn how to to get users with Firebase and how to work with real time data in Firestore using React Hooks.
security
If you're new here, like and subscribe, and you can reference the code on GitHub. And if you wanna go beyond the basics, check out this React Fire article by Jarrett Helton on Fireship IO. Before we get started, let's quickly take a look at what we're building today. It's a single group chat room that everybody can participate in, kind of like super chat on YouTube.
To enter the chat, a user must log in with their Google account. Once logged in, they can post messages into the chat, each message is a document in the Firestore database. It contains the text, user ID, and time stamp for that message. We make a query to the database for the most recent messages.
google
Is whenever the underlying data changes on the back end, the React app will update with the most recent messages on the front end. It's very easy to implement, and by the end of this video, you'll have a great starting point for building really any type of real time application. Let's go ahead and get started. Open up the terminal, and then I'll set a timer for 7 minutes. Run npx create React app to create an initial React project. Run code followed by the name of your app to open it in Versus Code. We have 2 extra dependencies to install, Firebase, and React Firebase Hooks. Once installed, we can open up the app JS file, which is where we'll write all of our front end code. Go ahead and delete the boilerplate code except for the app and the header. First, we'll import the Firebase SDK along with Firestore for our database and auth for user authentication. Then we'll import a couple of hooks here to make it easier to work with Firebase and React. We'll call Firebase initialize app to identify a project, and then we'll make a reference to the auth and Firestore SDKs as global variables. But we don't have a Firebase project yet, so let's create one by clicking add project from the Firebase site.
Once we get to the console, we can then tweak a couple of settings. To allow users to sign in with their Google account, we'll go to the authentication tab and enable Google sign in. From there, we'll go to the Cloud Firestore tab and enable the database. The last thing we'll do is click on the gear and then add a new web app to our project.
google
When you do that, it will give you a JavaScript object that identifies your project. Go ahead and copy those values and paste them into the Firebase initialize app in your source code. And now that we have Firebase set up, we need to architect this app. Here we have our main app component. If a user is signed in, we'll show the chat room. Otherwise, we'll show a button to sign in with Google. Knowing whether or not a user is logged in is dead simple with the use auth state hook. If a user is logged in, it returns an object that has a user ID, email address, and other info. When logged out, the user object is null. That means if we create additional components for sign in and chat room, we can then use a simple ternary operator to say, if the user is defined, show the chat room. Otherwise, show the sign in component. And now the question becomes, how do we sign in? In our sign in component, we'll return a button that listens to the click event and runs a function called sign in with Google. Inside that function, we instantiate a provider called the Google auth provider, then we pass it to the sign in with pop up method, which will trigger this pop up window when the user clicks on the button. It wouldn't hurt to add a sign out button as well. And in that component, we'll check to see if we have a current user, in which case we return a button that triggers the sign out method. And now we're ready to build our chat room. In Firestore, we have a collection of messages. When a user adds a new message to the chat, it creates a document in this collection along with a time stamp and their user ID.
In our code, we make a reference to this point in the database by calling Firestore collection. We can then make a query for a subset of documents, which we want ordered by the created at timestamp and limited to a maximum of 25, we can then make this query and listen to any updates to the data in real time with the use collection data hook.
databases
data management
It returns an array of objects where each object is the chat message in the database. And, again, anytime the data changes, React will rerender with the latest data. In the template, we can map over the array of messages. And for each message, we'll use a dedicated chat message component that has a key prop with the message ID and passes the document data as the message prop, we can then go and define the chat message child component, then we can show the actual text by accessing it from the props message. At this point, if you open up the Firestore console and add a new document to the messages collection, it should magically appear in your React UI and respond to any updates. Just make sure it has a text and created at field. Now when we display chat messages, we want to distinguish between messages that were sent and received. We can do that by comparing the user ID on the Firestore document to the currently logged in user. If they're equal, then we know the current user sent the message. We can then apply different styling based on whether or not the message was sent or received. You might also want to add a photo URL here as well. Okay. So now we need to wait in the UI for the user to send a message. We can start that feature off by adding a form below our messages list. Inside that form, we have a single input and then a button to submit the message, what we wanna do from there is add a stateful value to our component called form value. We can do that with the use state hook and have it start as an empty string. We can then go down to the input itself and bind its value to the form value state. Then whenever the user types into the form, it triggers the change event. So we'll listen to the on change event, then we'll take the value of the change and set it as the form value state. That takes care of the value the user types in the form, but now we need a way to submit it to write to the database. When the user clicks the button or submits the form, we can listen to the on submit event on the form itself and then we'll trigger an event handler called send a message. We'll define this as an async function in our component that takes the event as its argument. Normally, when a form is submitted, it will refresh the page. But we can call prevent default to stop that from happening. From there, we'll grab the user ID from the currently logged in user. Then we call await messages ref add, which will write a new document to the database. It takes a JavaScript object as its argument with the values that you want to write to the database. The text will be our form value. We'll give it a created at time stamp on the server and, of course, the user ID. That'll resolve when the document is created, and then we can reset our form value back to an empty string. And you should now be able to send messages in the chat and see them updated in the database. Now at this point, the main problem is that our app looks terrible. And the way we'll fix that is by going to the source code and copying the CSS from there. The reality is that CSS is way harder than React or Firebase and we're getting kind of short on time, we have some bigger problems to address with this app. First of all, when we enter a chat message, it doesn't automatically scroll to the bottom, which is kind of annoying. The way we can fix that is by adding an empty div below our list of chat messages. We can then reference that element with the ref prop and then connect it to our code with the use ref hook. Now that we have a reference to this element, we can go back into the send message function and we'll call scroll into view whenever the user sends a message.
And we now have a feature complete production ready UI without any bugs whatsoever. Now we can shift gears into the back end with our most important concern being security. In Firestore, you can use a JavaScript script like syntax to write security rules that you would otherwise have to implement on a back end server, we can modify our rules in the Firebase console.
security
We'll first match the path to the messages collection in the database. When a user wants to read a document, we wanna make sure that they're logged into their account. We can apply that logic by checking if the request auth user ID does not equal null, and it's just that simple.
databases
When it comes to creating a document, there are some additional things to think about. We wanna make sure a user is signed in, that they can only create documents with their own user ID, and that they're not banned for whatever reason. We can extract this logic into a custom function called can create message. We'll make sure they're logged in. We'll make sure that the user ID matches the user ID on the document they're trying to create.
I can also read other documents in the database. I have a banned collection for evil users. And if your user ID is in it, then you can't write to the database. Go ahead and click save, and we now have a fully secure app without any vulnerabilities whatsoever. We still have about a minute left, so let's go ahead and implement some back end code to filter out bad words and then ban users who violate the community guidelines, you can set up a serverless back end server by running Firebase init functions from the command line. That creates a node project in the functions directory. It can CD into it, and then we'll install the bad words package. From there, we can export a Cloud function that runs every time a new document is created in the messages collection, that'll give us access to the message text, which we can then check for profanity.
databases
security
software
If there is profanity, then we'll clean the text and then ban the user for life, when we're done, we can deploy the function by running Firebase deploy only functions. Congratulations. You just built a full stack chat app with React and Firebase. It's secure, flexible, scales infinitely in the cloud, and like any good social app, it enforces community guidelines.
I'm gonna go ahead and wrap things up there. If this video helped you, please like and subscribe. And in the near future, I'll be working on a full React Firebase course. It'll be available to pro members. And if you have any ideas, please feel free to leave them in the comments or let me know on our Slack channel.
youtube
Thanks for watching and I will see you in the next one.
Once upon a time, building a real time chat app required a lot of carefully engineered code. Today, when you combine tools like React and Firebase, you can build a basic chat app from scratch in under 7 minutes. The app you'll build today is live on the Internet, so feel free to check it out. Now I already know what most of you are thinking. You'll go into the live demo, say some terrible things, and try to break the app by spamming it with a ton of messages. But we can get a lot done in 7 minutes. There's plenty of time to implement security logic, and we'll even write some back end code to ban a user for life if they violate our community guidelines. But most importantly, you'll learn how to to get users with Firebase and how to work with real time data in Firestore using React Hooks. If you're new here, like and subscribe, and you can reference the code on GitHub. And if you wanna go beyond the basics, check out this React Fire article by Jarrett Helton on Fireship IO. Before we get started, let's quickly take a look at what we're building today. It's a single group chat room that everybody can participate in, kind of like super chat on YouTube. To enter the chat, a user must log in with their Google account. Once logged in, they can post messages into the chat, each message is a document in the Firestore database. It contains the text, user ID, and time stamp for that message. We make a query to the database for the most recent messages. Is whenever the underlying data changes on the back end, the React app will update with the most recent messages on the front end. It's very easy to implement, and by the end of this video, you'll have a great starting point for building really any type of real time application. Let's go ahead and get started. Open up the terminal, and then I'll set a timer for 7 minutes. Run npx create React app to create an initial React project. Run code followed by the name of your app to open it in Versus Code. We have 2 extra dependencies to install, Firebase, and React Firebase Hooks. Once installed, we can open up the app JS file, which is where we'll write all of our front end code. Go ahead and delete the boilerplate code except for the app and the header. First, we'll import the Firebase SDK along with Firestore for our database and auth for user authentication. Then we'll import a couple of hooks here to make it easier to work with Firebase and React. We'll call Firebase initialize app to identify a project, and then we'll make a reference to the auth and Firestore SDKs as global variables. But we don't have a Firebase project yet, so let's create one by clicking add project from the Firebase site. Once we get to the console, we can then tweak a couple of settings. To allow users to sign in with their Google account, we'll go to the authentication tab and enable Google sign in. From there, we'll go to the Cloud Firestore tab and enable the database. The last thing we'll do is click on the gear and then add a new web app to our project. When you do that, it will give you a JavaScript object that identifies your project. Go ahead and copy those values and paste them into the Firebase initialize app in your source code. And now that we have Firebase set up, we need to architect this app. Here we have our main app component. If a user is signed in, we'll show the chat room. Otherwise, we'll show a button to sign in with Google. Knowing whether or not a user is logged in is dead simple with the use auth state hook. If a user is logged in, it returns an object that has a user ID, email address, and other info. When logged out, the user object is null. That means if we create additional components for sign in and chat room, we can then use a simple ternary operator to say, if the user is defined, show the chat room. Otherwise, show the sign in component. And now the question becomes, how do we sign in? In our sign in component, we'll return a button that listens to the click event and runs a function called sign in with Google. Inside that function, we instantiate a provider called the Google auth provider, then we pass it to the sign in with pop up method, which will trigger this pop up window when the user clicks on the button. It wouldn't hurt to add a sign out button as well. And in that component, we'll check to see if we have a current user, in which case we return a button that triggers the sign out method. And now we're ready to build our chat room. In Firestore, we have a collection of messages. When a user adds a new message to the chat, it creates a document in this collection along with a time stamp and their user ID. In our code, we make a reference to this point in the database by calling Firestore collection. We can then make a query for a subset of documents, which we want ordered by the created at timestamp and limited to a maximum of 25, we can then make this query and listen to any updates to the data in real time with the use collection data hook. It returns an array of objects where each object is the chat message in the database. And, again, anytime the data changes, React will rerender with the latest data. In the template, we can map over the array of messages. And for each message, we'll use a dedicated chat message component that has a key prop with the message ID and passes the document data as the message prop, we can then go and define the chat message child component, then we can show the actual text by accessing it from the props message. At this point, if you open up the Firestore console and add a new document to the messages collection, it should magically appear in your React UI and respond to any updates. Just make sure it has a text and created at field. Now when we display chat messages, we want to distinguish between messages that were sent and received. We can do that by comparing the user ID on the Firestore document to the currently logged in user. If they're equal, then we know the current user sent the message. We can then apply different styling based on whether or not the message was sent or received. You might also want to add a photo URL here as well. Okay. So now we need to wait in the UI for the user to send a message. We can start that feature off by adding a form below our messages list. Inside that form, we have a single input and then a button to submit the message, what we wanna do from there is add a stateful value to our component called form value. We can do that with the use state hook and have it start as an empty string. We can then go down to the input itself and bind its value to the form value state. Then whenever the user types into the form, it triggers the change event. So we'll listen to the on change event, then we'll take the value of the change and set it as the form value state. That takes care of the value the user types in the form, but now we need a way to submit it to write to the database. When the user clicks the button or submits the form, we can listen to the on submit event on the form itself and then we'll trigger an event handler called send a message. We'll define this as an async function in our component that takes the event as its argument. Normally, when a form is submitted, it will refresh the page. But we can call prevent default to stop that from happening. From there, we'll grab the user ID from the currently logged in user. Then we call await messages ref add, which will write a new document to the database. It takes a JavaScript object as its argument with the values that you want to write to the database. The text will be our form value. We'll give it a created at time stamp on the server and, of course, the user ID. That'll resolve when the document is created, and then we can reset our form value back to an empty string. And you should now be able to send messages in the chat and see them updated in the database. Now at this point, the main problem is that our app looks terrible. And the way we'll fix that is by going to the source code and copying the CSS from there. The reality is that CSS is way harder than React or Firebase and we're getting kind of short on time, we have some bigger problems to address with this app. First of all, when we enter a chat message, it doesn't automatically scroll to the bottom, which is kind of annoying. The way we can fix that is by adding an empty div below our list of chat messages. We can then reference that element with the ref prop and then connect it to our code with the use ref hook. Now that we have a reference to this element, we can go back into the send message function and we'll call scroll into view whenever the user sends a message. And we now have a feature complete production ready UI without any bugs whatsoever. Now we can shift gears into the back end with our most important concern being security. In Firestore, you can use a JavaScript script like syntax to write security rules that you would otherwise have to implement on a back end server, we can modify our rules in the Firebase console. We'll first match the path to the messages collection in the database. When a user wants to read a document, we wanna make sure that they're logged into their account. We can apply that logic by checking if the request auth user ID does not equal null, and it's just that simple. When it comes to creating a document, there are some additional things to think about. We wanna make sure a user is signed in, that they can only create documents with their own user ID, and that they're not banned for whatever reason. We can extract this logic into a custom function called can create message. We'll make sure they're logged in. We'll make sure that the user ID matches the user ID on the document they're trying to create. I can also read other documents in the database. I have a banned collection for evil users. And if your user ID is in it, then you can't write to the database. Go ahead and click save, and we now have a fully secure app without any vulnerabilities whatsoever. We still have about a minute left, so let's go ahead and implement some back end code to filter out bad words and then ban users who violate the community guidelines, you can set up a serverless back end server by running Firebase init functions from the command line. That creates a node project in the functions directory. It can CD into it, and then we'll install the bad words package. From there, we can export a Cloud function that runs every time a new document is created in the messages collection, that'll give us access to the message text, which we can then check for profanity. If there is profanity, then we'll clean the text and then ban the user for life, when we're done, we can deploy the function by running Firebase deploy only functions. Congratulations. You just built a full stack chat app with React and Firebase. It's secure, flexible, scales infinitely in the cloud, and like any good social app, it enforces community guidelines. I'm gonna go ahead and wrap things up there. If this video helped you, please like and subscribe. And in the near future, I'll be working on a full React Firebase course. It'll be available to pro members. And if you have any ideas, please feel free to leave them in the comments or let me know on our Slack channel. Thanks for watching and I will see you in the next one.
Once
once
upon
upon
a
a
time,
time
building
building
a
a
real
real
time
time
chat
chat
app
app
required
required
a
a
lot
lot
of
of
carefully
carefully
engineered
engineered
code.
code
Today,
today
when
when
you
you
combine
combine
tools
tools
like
like
React
react
and
and
Firebase,
firebase
you
you
can
can
build
build
a
a
basic
basic
chat
chat
app
app
from
from
scratch
scratch
in
in
under
under
7
7
minutes.
minutes
The
the
app
app
you'll
you'll
build
build
today
today
is
is
live
live
on
on
the
the
Internet,
internet
so
so
feel
feel
free
free
to
to
check
check
it
it
out.
out
Now
now
I
i
already
already
know
know
what
what
most
most
of
of
you
you
are
are
thinking.
thinking
You'll
you'll
go
go
into
into
the
the
live
live
demo,
demo
say
say
some
some
terrible
terrible
things,
things
and
and
try
try
to
to
break
break
the
the
app
app
by
by
spamming
spamming
it
it
with
with
a
a
ton
ton
of
of
messages.
messages
But
but
we
we
can
can
get
get
a
a
lot
lot
done
done
in
in
7
7
minutes.
minutes
There's
there's
plenty
plenty
of
of
time
time
to
to
implement
implement
security
security
logic,
logic
and
and
we'll
we'll
even
even
write
write
some
some
back
back
end
end
code
code
to
to
ban
ban
a
a
user
user
for
for
life
life
if
if
they
they
violate
violate
our
our
community
community
guidelines.
guidelines
But
but
most
most
importantly,
importantly
you'll
you'll
learn
learn
how
how
to
to
to
to
get
get
users
users
with
with
Firebase
firebase
and
and
how
how
to
to
work
work
with
with
real
real
time
time
data
data
in
in
Firestore
firestore
using
using
React
react
Hooks.
hooks
If
if
you're
you're
new
new
here,
here
like
like
and
and
subscribe,
subscribe
and
and
you
you
can
can
reference
reference
the
the
code
code
on
on
GitHub.
github
And
and
if
if
you
you
wanna
wanna
go
go
beyond
beyond
the
the
basics,
basics
check
check
out
out
this
this
React
react
Fire
fire
article
article
by
by
Jarrett
jarrett
Helton
helton
on
on
Fireship
fireship
IO.
io
Before
before
we
we
get
get
started,
started
let's
let's
quickly
quickly
take
take
a
a
look
look
at
at
what
what
we're
we're
building
building
today.
today
It's
it's
a
a
single
single
group
group
chat
chat
room
room
that
that
everybody
everybody
can
can
participate
participate
in,
in
kind
kind
of
of
like
like
super
super
chat
chat
on
on
YouTube.
youtube
To
to
enter
enter
the
the
chat,
chat
a
a
user
user
must
must
log
log
in
in
with
with
their
their
Google
google
account.
account
Once
once
logged
logged
in,
in
they
they
can
can
post
post
messages
messages
into
into
the
the
chat,
chat
each
each
message
message
is
is
a
a
document
document
in
in
the
the
Firestore
firestore
database.
database
It
it
contains
contains
the
the
text,
text
user
user
ID,
id
and
and
time
time
stamp
stamp
for
for
that
that
message.
message
We
we
make
make
a
a
query
query
to
to
the
the
database
database
for
for
the
the
most
most
recent
recent
messages.
messages
Is
is
whenever
whenever
the
the
underlying
underlying
data
data
changes
changes
on
on
the
the
back
back
end,
end
the
the
React
react
app
app
will
will
update
update
with
with
the
the
most
most
recent
recent
messages
messages
on
on
the
the
front
front
end.
end
It's
it's
very
very
easy
easy
to
to
implement,
implement
and
and
by
by
the
the
end
end
of
of
this
this
video,
video
you'll
you'll
have
have
a
a
great
great
starting
starting
point
point
for
for
building
building
really
really
any
any
type
type
of
of
real
real
time
time
application.
application
Let's
let's
go
go
ahead
ahead
and
and
get
get
started.
started
Open
open
up
up
the
the
terminal,
terminal
and
and
then
then
I'll
i'll
set
set
a
a
timer
timer
for
for
7
7
minutes.
minutes
Run
run
npx
npx
create
create
React
react
app
app
to
to
create
create
an
an
initial
initial
React
react
project.
project
Run
run
code
code
followed
followed
by
by
the
the
name
name
of
of
your
your
app
app
to
to
open
open
it
it
in
in
Versus
versus
Code.
code
We
we
have
have
2
2
extra
extra
dependencies
dependencies
to
to
install,
install
Firebase,
firebase
and
and
React
react
Firebase
firebase
Hooks.
hooks
Once
once
installed,
installed
we
we
can
can
open
open
up
up
the
the
app
app
JS
js
file,
file
which
which
is
is
where
where
we'll
we'll
write
write
all
all
of
of
our
our
front
front
end
end
code.
code
Go
go
ahead
ahead
and
and
delete
delete
the
the
boilerplate
boilerplate
code
code
except
except
for
for
the
the
app
app
and
and
the
the
header.
header
First,
first
we'll
we'll
import
import
the
the
Firebase
firebase
SDK
sdk
along
along
with
with
Firestore
firestore
for
for
our
our
database
database
and
and
auth
auth
for
for
user
user
authentication.
authentication
Then
then
we'll
we'll
import
import
a
a
couple
couple
of
of
hooks
hooks
here
here
to
to
make
make
it
it
easier
easier
to
to
work
work
with
with
Firebase
firebase
and
and
React.
react
We'll
we'll
call
call
Firebase
firebase
initialize
initialize
app
app
to
to
identify
identify
a
a
project,
project
and
and
then
then
we'll
we'll
make
make
a
a
reference
reference
to
to
the
the
auth
auth
and
and
Firestore
firestore
SDKs
sdks
as
as
global
global
variables.
variables
But
but
we
we
don't
don't
have
have
a
a
Firebase
firebase
project
project
yet,
yet
so
so
let's
let's
create
create
one
one
by
by
clicking
clicking
add
add
project
project
from
from
the
the
Firebase
firebase
site.
site
Once
once
we
we
get
get
to
to
the
the
console,
console
we
we
can
can
then
then
tweak
tweak
a
a
couple
couple
of
of
settings.
settings
To
to
allow
allow
users
users
to
to
sign
sign
in
in
with
with
their
their
Google
google
account,
account
we'll
we'll
go
go
to
to
the
the
authentication
authentication
tab
tab
and
and
enable
enable
Google
google
sign
sign
in.
in
From
from
there,
there
we'll
we'll
go
go
to
to
the
the
Cloud
cloud
Firestore
firestore
tab
tab
and
and
enable
enable
the
the
database.
database
The
the
last
last
thing
thing
we'll
we'll
do
do
is
is
click
click
on
on
the
the
gear
gear
and
and
then
then
add
add
a
a
new
new
web
web
app
app
to
to
our
our
project.
project
When
when
you
you
do
do
that,
that
it
it
will
will
give
give
you
you
a
a
JavaScript
javascript
object
object
that
that
identifies
identifies
your
your
project.
project
Go
go
ahead
ahead
and
and
copy
copy
those
those
values
values
and
and
paste
paste
them
them
into
into
the
the
Firebase
firebase
initialize
initialize
app
app
in
in
your
your
source
source
code.
code
And
and
now
now
that
that
we
we
have
have
Firebase
firebase
set
set
up,
up
we
we
need
need
to
to
architect
architect
this
this
app.
app
Here
here
we
we
have
have
our
our
main
main
app
app
component.
component
If
if
a
a
user
user
is
is
signed
signed
in,
in
we'll
we'll
show
show
the
the
chat
chat
room.
room
Otherwise,
otherwise
we'll
we'll
show
show
a
a
button
button
to
to
sign
sign
in
in
with
with
Google.
google
Knowing
knowing
whether
whether
or
or
not
not
a
a
user
user
is
is
logged
logged
in
in
is
is
dead
dead
simple
simple
with
with
the
the
use
use
auth
auth
state
state
hook.
hook
If
if
a
a
user
user
is
is
logged
logged
in,
in
it
it
returns
returns
an
an
object
object
that
that
has
has
a
a
user
user
ID,
id
email
email
address,
address
and
and
other
other
info.
info
When
when
logged
logged
out,
out
the
the
user
user
object
object
is
is
null.
null
That
that
means
means
if
if
we
we
create
create
additional
additional
components
components
for
for
sign
sign
in
in
and
and
chat
chat
room,
room
we
we
can
can
then
then
use
use
a
a
simple
simple
ternary
ternary
operator
operator
to
to
say,
say
if
if
the
the
user
user
is
is
defined,
defined
show
show
the
the
chat
chat
room.
room
Otherwise,
otherwise
show
show
the
the
sign
sign
in
in
component.
component
And
and
now
now
the
the
question
question
becomes,
becomes
how
how
do
do
we
we
sign
sign
in?
in
In
in
our
our
sign
sign
in
in
component,
component
we'll
we'll
return
return
a
a
button
button
that
that
listens
listens
to
to
the
the
click
click
event
event
and
and
runs
runs
a
a
function
function
called
called
sign
sign
in
in
with
with
Google.
google
Inside
inside
that
that
function,
function
we
we
instantiate
instantiate
a
a
provider
provider
called
called
the
the
Google
google
auth
auth
provider,
provider
then
then
we
we
pass
pass
it
it
to
to
the
the
sign
sign
in
in
with
with
pop
pop
up
up
method,
method
which
which
will
will
trigger
trigger
this
this
pop
pop
up
up
window
window
when
when
the
the
user
user
clicks
clicks
on
on
the
the
button.
button
It
it
wouldn't
wouldn't
hurt
hurt
to
to
add
add
a
a
sign
sign
out
out
button
button
as
as
well.
well
And
and
in
in
that
that
component,
component
we'll
we'll
check
check
to
to
see
see
if
if
we
we
have
have
a
a
current
current
user,
user
in
in
which
which
case
case
we
we
return
return
a
a
button
button
that
that
triggers
triggers
the
the
sign
sign
out
out
method.
method
And
and
now
now
we're
we're
ready
ready
to
to
build
build
our
our
chat
chat
room.
room
In
in
Firestore,
firestore
we
we
have
have
a
a
collection
collection
of
of
messages.
messages
When
when
a
a
user
user
adds
adds
a
a
new
new
message
message
to
to
the
the
chat,
chat
it
it
creates
creates
a
a
document
document
in
in
this
this
collection
collection
along
along
with
with
a
a
time
time
stamp
stamp
and
and
their
their
user
user
ID.
id
In
in
our
our
code,
code
we
we
make
make
a
a
reference
reference
to
to
this
this
point
point
in
in
the
the
database
database
by
by
calling
calling
Firestore
firestore
collection.
collection
We
we
can
can
then
then
make
make
a
a
query
query
for
for
a
a
subset
subset
of
of
documents,
documents
which
which
we
we
want
want
ordered
ordered
by
by
the
the
created
created
at
at
timestamp
timestamp
and
and
limited
limited
to
to
a
a
maximum
maximum
of
of
25,
25
we
we
can
can
then
then
make
make
this
this
query
query
and
and
listen
listen
to
to
any
any
updates
updates
to
to
the
the
data
data
in
in
real
real
time
time
with
with
the
the
use
use
collection
collection
data
data
hook.
hook
It
it
returns
returns
an
an
array
array
of
of
objects
objects
where
where
each
each
object
object
is
is
the
the
chat
chat
message
message
in
in
the
the
database.
database
And,
and
again,
again
anytime
anytime
the
the
data
data
changes,
changes
React
react
will
will
rerender
rerender
with
with
the
the
latest
latest
data.
data
In
in
the
the
template,
template
we
we
can
can
map
map
over
over
the
the
array
array
of
of
messages.
messages
And
and
for
for
each
each
message,
message
we'll
we'll
use
use
a
a
dedicated
dedicated
chat
chat
message
message
component
component
that
that
has
has
a
a
key
key
prop
prop
with
with
the
the
message
message
ID
id
and
and
passes
passes
the
the
document
document
data
data
as
as
the
the
message
message
prop,
prop
we
we
can
can
then
then
go
go
and
and
define
define
the
the
chat
chat
message
message
child
child
component,
component
then
then
we
we
can
can
show
show
the
the
actual
actual
text
text
by
by
accessing
accessing
it
it
from
from
the
the
props
props
message.
message
At
at
this
this
point,
point
if
if
you
you
open
open
up
up
the
the
Firestore
firestore
console
console
and
and
add
add
a
a
new
new
document
document
to
to
the
the
messages
messages
collection,
collection
it
it
should
should
magically
magically
appear
appear
in
in
your
your
React
react
UI
ui
and
and
respond
respond
to
to
any
any
updates.
updates
Just
just
make
make
sure
sure
it
it
has
has
a
a
text
text
and
and
created
created
at
at
field.
field
Now
now
when
when
we
we
display
display
chat
chat
messages,
messages
we
we
want
want
to
to
distinguish
distinguish
between
between
messages
messages
that
that
were
were
sent
sent
and
and
received.
received
We
we
can
can
do
do
that
that
by
by
comparing
comparing
the
the
user
user
ID
id
on
on
the
the
Firestore
firestore
document
document
to
to
the
the
currently
currently
logged
logged
in
in
user.
user
If
if
they're
they're
equal,
equal
then
then
we
we
know
know
the
the
current
current
user
user
sent
sent
the
the
message.
message
We
we
can
can
then
then
apply
apply
different
different
styling
styling
based
based
on
on
whether
whether
or
or
not
not
the
the
message
message
was
was
sent
sent
or
or
received.
received
You
you
might
might
also
also
want
want
to
to
add
add
a
a
photo
photo
URL
url
here
here
as
as
well.
well
Okay.
okay
So
so
now
now
we
we
need
need
to
to
wait
wait
in
in
the
the
UI
ui
for
for
the
the
user
user
to
to
send
send
a
a
message.
message
We
we
can
can
start
start
that
that
feature
feature
off
off
by
by
adding
adding
a
a
form
form
below
below
our
our
messages
messages
list.
list
Inside
inside
that
that
form,
form
we
we
have
have
a
a
single
single
input
input
and
and
then
then
a
a
button
button
to
to
submit
submit
the
the
message,
message
what
what
we
we
wanna
wanna
do
do
from
from
there
there
is
is
add
add
a
a
stateful
stateful
value
value
to
to
our
our
component
component
called
called
form
form
value.
value
We
we
can
can
do
do
that
that
with
with
the
the
use
use
state
state
hook
hook
and
and
have
have
it
it
start
start
as
as
an
an
empty
empty
string.
string
We
we
can
can
then
then
go
go
down
down
to
to
the
the
input
input
itself
itself
and
and
bind
bind
its
its
value
value
to
to
the
the
form
form
value
value
state.
state
Then
then
whenever
whenever
the
the
user
user
types
types
into
into
the
the
form,
form
it
it
triggers
triggers
the
the
change
change
event.
event
So
so
we'll
we'll
listen
listen
to
to
the
the
on
on
change
change
event,
event
then
then
we'll
we'll
take
take
the
the
value
value
of
of
the
the
change
change
and
and
set
set
it
it
as
as
the
the
form
form
value
value
state.
state
That
that
takes
takes
care
care
of
of
the
the
value
value
the
the
user
user
types
types
in
in
the
the
form,
form
but
but
now
now
we
we
need
need
a
a
way
way
to
to
submit
submit
it
it
to
to
write
write
to
to
the
the
database.
database
When
when
the
the
user
user
clicks
clicks
the
the
button
button
or
or
submits
submits
the
the
form,
form
we
we
can
can
listen
listen
to
to
the
the
on
on
submit
submit
event
event
on
on
the
the
form
form
itself
itself
and
and
then
then
we'll
we'll
trigger
trigger
an
an
event
event
handler
handler
called
called
send
send
a
a
message.
message
We'll
we'll
define
define
this
this
as
as
an
an
async
async
function
function
in
in
our
our
component
component
that
that
takes
takes
the
the
event
event
as
as
its
its
argument.
argument
Normally,
normally
when
when
a
a
form
form
is
is
submitted,
submitted
it
it
will
will
refresh
refresh
the
the
page.
page
But
but
we
we
can
can
call
call
prevent
prevent
default
default
to
to
stop
stop
that
that
from
from
happening.
happening
From
from
there,
there
we'll
we'll
grab
grab
the
the
user
user
ID
id
from
from
the
the
currently
currently
logged
logged
in
in
user.
user
Then
then
we
we
call
call
await
await
messages
messages
ref
ref
add,
add
which
which
will
will
write
write
a
a
new
new
document
document
to
to
the
the
database.
database
It
it
takes
takes
a
a
JavaScript
javascript
object
object
as
as
its
its
argument
argument
with
with
the
the
values
values
that
that
you
you
want
want
to
to
write
write
to
to
the
the
database.
database
The
the
text
text
will
will
be
be
our
our
form
form
value.
value
We'll
we'll
give
give
it
it
a
a
created
created
at
at
time
time
stamp
stamp
on
on
the
the
server
server
and,
and
of
of
course,
course
the
the
user
user
ID.
id
That'll
that'll
resolve
resolve
when
when
the
the
document
document
is
is
created,
created
and
and
then
then
we
we
can
can
reset
reset
our
our
form
form
value
value
back
back
to
to
an
an
empty
empty
string.
string
And
and
you
you
should
should
now
now
be
be
able
able
to
to
send
send
messages
messages
in
in
the
the
chat
chat
and
and
see
see
them
them
updated
updated
in
in
the
the
database.
database
Now
now
at
at
this
this
point,
point
the
the
main
main
problem
problem
is
is
that
that
our
our
app
app
looks
looks
terrible.
terrible
And
and
the
the
way
way
we'll
we'll
fix
fix
that
that
is
is
by
by
going
going
to
to
the
the
source
source
code
code
and
and
copying
copying
the
the
CSS
css
from
from
there.
there
The
the
reality
reality
is
is
that
that
CSS
css
is
is
way
way
harder
harder
than
than
React
react
or
or
Firebase
firebase
and
and
we're
we're
getting
getting
kind
kind
of
of
short
short
on
on
time,
time
we
we
have
have
some
some
bigger
bigger
problems
problems
to
to
address
address
with
with
this
this
app.
app
First
first
of
of
all,
all
when
when
we
we
enter
enter
a
a
chat
chat
message,
message
it
it
doesn't
doesn't
automatically
automatically
scroll
scroll
to
to
the
the
bottom,
bottom
which
which
is
is
kind
kind
of
of
annoying.
annoying
The
the
way
way
we
we
can
can
fix
fix
that
that
is
is
by
by
adding
adding
an
an
empty
empty
div
div
below
below
our
our
list
list
of
of
chat
chat
messages.
messages
We
we
can
can
then
then
reference
reference
that
that
element
element
with
with
the
the
ref
ref
prop
prop
and
and
then
then
connect
connect
it
it
to
to
our
our
code
code
with
with
the
the
use
use
ref
ref
hook.
hook
Now
now
that
that
we
we
have
have
a
a
reference
reference
to
to
this
this
element,
element
we
we
can
can
go
go
back
back
into
into
the
the
send
send
message
message
function
function
and
and
we'll
we'll
call
call
scroll
scroll
into
into
view
view
whenever
whenever
the
the
user
user
sends
sends
a
a
message.
message
And
and
we
we
now
now
have
have
a
a
feature
feature
complete
complete
production
production
ready
ready
UI
ui
without
without
any
any
bugs
bugs
whatsoever.
whatsoever
Now
now
we
we
can
can
shift
shift
gears
gears
into
into
the
the
back
back
end
end
with
with
our
our
most
most
important
important
concern
concern
being
being
security.
security
In
in
Firestore,
firestore
you
you
can
can
use
use
a
a
JavaScript
javascript
script
script
like
like
syntax
syntax
to
to
write
write
security
security
rules
rules
that
that
you
you
would
would
otherwise
otherwise
have
have
to
to
implement
implement
on
on
a
a
back
back
end
end
server,
server
we
we
can
can
modify
modify
our
our
rules
rules
in
in
the
the
Firebase
firebase
console.
console
We'll
we'll
first
first
match
match
the
the
path
path
to
to
the
the
messages
messages
collection
collection
in
in
the
the
database.
database
When
when
a
a
user
user
wants
wants
to
to
read
read
a
a
document,
document
we
we
wanna
wanna
make
make
sure
sure
that
that
they're
they're
logged
logged
into
into
their
their
account.
account
We
we
can
can
apply
apply
that
that
logic
logic
by
by
checking
checking
if
if
the
the
request
request
auth
auth
user
user
ID
id
does
does
not
not
equal
equal
null,
null
and
and
it's
it's
just
just
that
that
simple.
simple
When
when
it
it
comes
comes
to
to
creating
creating
a
a
document,
document
there
there
are
are
some
some
additional
additional
things
things
to
to
think
think
about.
about
We
we
wanna
wanna
make
make
sure
sure
a
a
user
user
is
is
signed
signed
in,
in
that
that
they
they
can
can
only
only
create
create
documents
documents
with
with
their
their
own
own
user
user
ID,
id
and
and
that
that
they're
they're
not
not
banned
banned
for
for
whatever
whatever
reason.
reason
We
we
can
can
extract
extract
this
this
logic
logic
into
into
a
a
custom
custom
function
function
called
called
can
can
create
create
message.
message
We'll
we'll
make
make
sure
sure
they're
they're
logged
logged
in.
in
We'll
we'll
make
make
sure
sure
that
that
the
the
user
user
ID
id
matches
matches
the
the
user
user
ID
id
on
on
the
the
document
document
they're
they're
trying
trying
to
to
create.
create
I
i
can
can
also
also
read
read
other
other
documents
documents
in
in
the
the
database.
database
I
i
have
have
a
a
banned
banned
collection
collection
for
for
evil
evil
users.
users
And
and
if
if
your
your
user
user
ID
id
is
is
in
in
it,
it
then
then
you
you
can't
can't
write
write
to
to
the
the
database.
database
Go
go
ahead
ahead
and
and
click
click
save,
save
and
and
we
we
now
now
have
have
a
a
fully
fully
secure
secure
app
app
without
without
any
any
vulnerabilities
vulnerabilities
whatsoever.
whatsoever
We
we
still
still
have
have
about
about
a
a
minute
minute
left,
left
so
so
let's
let's
go
go
ahead
ahead
and
and
implement
implement
some
some
back
back
end
end
code
code
to
to
filter
filter
out
out
bad
bad
words
words
and
and
then
then
ban
ban
users
users
who
who
violate
violate
the
the
community
community
guidelines,
guidelines
you
you
can
can
set
set
up
up
a
a
serverless
serverless
back
back
end
end
server
server
by
by
running
running
Firebase
firebase
init
init
functions
functions
from
from
the
the
command
command
line.
line
That
that
creates
creates
a
a
node
node
project
project
in
in
the
the
functions
functions
directory.
directory
It
it
can
can
CD
cd
into
into
it,
it
and
and
then
then
we'll
we'll
install
install
the
the
bad
bad
words
words
package.
package
From
from
there,
there
we
we
can
can
export
export
a
a
Cloud
cloud
function
function
that
that
runs
runs
every
every
time
time
a
a
new
new
document
document
is
is
created
created
in
in
the
the
messages
messages
collection,
collection
that'll
that'll
give
give
us
us
access
access
to
to
the
the
message
message
text,
text
which
which
we
we
can
can
then
then
check
check
for
for
profanity.
profanity
If
if
there
there
is
is
profanity,
profanity
then
then
we'll
we'll
clean
clean
the
the
text
text
and
and
then
then
ban
ban
the
the
user
user
for
for
life,
life
when
when
we're
we're
done,
done
we
we
can
can
deploy
deploy
the
the
function
function
by
by
running
running
Firebase
firebase
deploy
deploy
only
only
functions.
functions
Congratulations.
congratulations
You
you
just
just
built
built
a
a
full
full
stack
stack
chat
chat
app
app
with
with
React
react
and
and
Firebase.
firebase
It's
it's
secure,
secure
flexible,
flexible
scales
scales
infinitely
infinitely
in
in
the
the
cloud,
cloud
and
and
like
like
any
any
good
good
social
social
app,
app
it
it
enforces
enforces
community
community
guidelines.
guidelines
I'm
i'm
gonna
gonna
go
go
ahead
ahead
and
and
wrap
wrap
things
things
up
up
there.
there
If
if
this
this
video
video
helped
helped
you,
you
please
please
like
like
and
and
subscribe.
subscribe
And
and
in
in
the
the
near
near
future,
future
I'll
i'll
be
be
working
working
on
on
a
a
full
full
React
react
Firebase
firebase
course.
course
It'll
it'll
be
be
available
available
to
to
pro
pro
members.
members
And
and
if
if
you
you
have
have
any
any
ideas,
ideas
please
please
feel
feel
free
free
to
to
leave
leave
them
them
in
in
the
the
comments
comments
or
or
let
let
me
me
know
know
on
on
our
our
Slack
slack
channel.
channel
Thanks
thanks
for
for
watching
watching
and
and
I
i
will
will
see
see
you
you
in
in
the
the
next
next
one.
one
success
The speakers discuss building a real time chat app using React Hooks and security logic, as well as building a single group chat room and using native code in Firwork IO. They also explain the process of creating a chat room, including importation of necessary resources and setting up a web app. The use authorization state hook and the useflow process for signing in and chat room are also discussed, along with the use of a Google denies account and a code component to sign in and chat. The speakers also explain how to use the React UI to display chat messages and differentiate between messages sent and received, as well as the use state hook and the addition of a photo URL. They conclude by offering a full React Guinea course and encouraging viewers to like and subscribe.
I built a chat app in 7 minutes with React & Firebase
Once upon a time, building a real time chat app required a lot of carefully engineered code. Today, when you combine tools like React and Firebase, you can build a basic chat app from scratch in under 7 minutes. The app you'll build today is live on the Internet, so feel free to check it out. Now I already know what most of you are thinking. You'll go into the live demo, say some terrible things, and try to break the app by spamming it with a ton of messages. But we can get a lot done in 7 minutes. There's plenty of time to implement security logic, and we'll even write some back end code to ban a user for life if they violate our community guidelines. But most importantly, you'll learn how to to get users with Firebase and how to work with real time data in Firestore using React Hooks. If you're new here, like and subscribe, and you can reference the code on GitHub. And if you wanna go beyond the basics, check out this React Fire article by Jarrett Helton on Fireship IO. Before we get started, let's quickly take a look at what we're building today. It's a single group chat room that everybody can participate in, kind of like super chat on YouTube. To enter the chat, a user must log in with their Google account. Once logged in, they can post messages into the chat, each message is a document in the Firestore database. It contains the text, user ID, and time stamp for that message. We make a query to the database for the most recent messages. Is whenever the underlying data changes on the back end, the React app will update with the most recent messages on the front end. It's very easy to implement, and by the end of this video, you'll have a great starting point for building really any type of real time application. Let's go ahead and get started. Open up the terminal, and then I'll set a timer for 7 minutes. Run npx create React app to create an initial React project. Run code followed by the name of your app to open it in Versus Code. We have 2 extra dependencies to install, Firebase, and React Firebase Hooks. Once installed, we can open up the app JS file, which is where we'll write all of our front end code. Go ahead and delete the boilerplate code except for the app and the header. First, we'll import the Firebase SDK along with Firestore for our database and auth for user authentication. Then we'll import a couple of hooks here to make it easier to work with Firebase and React. We'll call Firebase initialize app to identify a project, and then we'll make a reference to the auth and Firestore SDKs as global variables. But we don't have a Firebase project yet, so let's create one by clicking add project from the Firebase site. Once we get to the console, we can then tweak a couple of settings. To allow users to sign in with their Google account, we'll go to the authentication tab and enable Google sign in. From there, we'll go to the Cloud Firestore tab and enable the database. The last thing we'll do is click on the gear and then add a new web app to our project. When you do that, it will give you a JavaScript object that identifies your project. Go ahead and copy those values and paste them into the Firebase initialize app in your source code. And now that we have Firebase set up, we need to architect this app. Here we have our main app component. If a user is signed in, we'll show the chat room. Otherwise, we'll show a button to sign in with Google. Knowing whether or not a user is logged in is dead simple with the use auth state hook. If a user is logged in, it returns an object that has a user ID, email address, and other info. When logged out, the user object is null. That means if we create additional components for sign in and chat room, we can then use a simple ternary operator to say, if the user is defined, show the chat room. Otherwise, show the sign in component. And now the question becomes, how do we sign in? In our sign in component, we'll return a button that listens to the click event and runs a function called sign in with Google. Inside that function, we instantiate a provider called the Google auth provider, then we pass it to the sign in with pop up method, which will trigger this pop up window when the user clicks on the button. It wouldn't hurt to add a sign out button as well. And in that component, we'll check to see if we have a current user, in which case we return a button that triggers the sign out method. And now we're ready to build our chat room. In Firestore, we have a collection of messages. When a user adds a new message to the chat, it creates a document in this collection along with a time stamp and their user ID. In our code, we make a reference to this point in the database by calling Firestore collection. We can then make a query for a subset of documents, which we want ordered by the created at timestamp and limited to a maximum of 25, we can then make this query and listen to any updates to the data in real time with the use collection data hook. It returns an array of objects where each object is the chat message in the database. And, again, anytime the data changes, React will rerender with the latest data. In the template, we can map over the array of messages. And for each message, we'll use a dedicated chat message component that has a key prop with the message ID and passes the document data as the message prop, we can then go and define the chat message child component, then we can show the actual text by accessing it from the props message. At this point, if you open up the Firestore console and add a new document to the messages collection, it should magically appear in your React UI and respond to any updates. Just make sure it has a text and created at field. Now when we display chat messages, we want to distinguish between messages that were sent and received. We can do that by comparing the user ID on the Firestore document to the currently logged in user. If they're equal, then we know the current user sent the message. We can then apply different styling based on whether or not the message was sent or received. You might also want to add a photo URL here as well. Okay. So now we need to wait in the UI for the user to send a message. We can start that feature off by adding a form below our messages list. Inside that form, we have a single input and then a button to submit the message, what we wanna do from there is add a stateful value to our component called form value. We can do that with the use state hook and have it start as an empty string. We can then go down to the input itself and bind its value to the form value state. Then whenever the user types into the form, it triggers the change event. So we'll listen to the on change event, then we'll take the value of the change and set it as the form value state. That takes care of the value the user types in the form, but now we need a way to submit it to write to the database. When the user clicks the button or submits the form, we can listen to the on submit event on the form itself and then we'll trigger an event handler called send a message. We'll define this as an async function in our component that takes the event as its argument. Normally, when a form is submitted, it will refresh the page. But we can call prevent default to stop that from happening. From there, we'll grab the user ID from the currently logged in user. Then we call await messages ref add, which will write a new document to the database. It takes a JavaScript object as its argument with the values that you want to write to the database. The text will be our form value. We'll give it a created at time stamp on the server and, of course, the user ID. That'll resolve when the document is created, and then we can reset our form value back to an empty string. And you should now be able to send messages in the chat and see them updated in the database. Now at this point, the main problem is that our app looks terrible. And the way we'll fix that is by going to the source code and copying the CSS from there. The reality is that CSS is way harder than React or Firebase and we're getting kind of short on time, we have some bigger problems to address with this app. First of all, when we enter a chat message, it doesn't automatically scroll to the bottom, which is kind of annoying. The way we can fix that is by adding an empty div below our list of chat messages. We can then reference that element with the ref prop and then connect it to our code with the use ref hook. Now that we have a reference to this element, we can go back into the send message function and we'll call scroll into view whenever the user sends a message. And we now have a feature complete production ready UI without any bugs whatsoever. Now we can shift gears into the back end with our most important concern being security. In Firestore, you can use a JavaScript script like syntax to write security rules that you would otherwise have to implement on a back end server, we can modify our rules in the Firebase console. We'll first match the path to the messages collection in the database. When a user wants to read a document, we wanna make sure that they're logged into their account. We can apply that logic by checking if the request auth user ID does not equal null, and it's just that simple. When it comes to creating a document, there are some additional things to think about. We wanna make sure a user is signed in, that they can only create documents with their own user ID, and that they're not banned for whatever reason. We can extract this logic into a custom function called can create message. We'll make sure they're logged in. We'll make sure that the user ID matches the user ID on the document they're trying to create. I can also read other documents in the database. I have a banned collection for evil users. And if your user ID is in it, then you can't write to the database. Go ahead and click save, and we now have a fully secure app without any vulnerabilities whatsoever. We still have about a minute left, so let's go ahead and implement some back end code to filter out bad words and then ban users who violate the community guidelines, you can set up a serverless back end server by running Firebase init functions from the command line. That creates a node project in the functions directory. It can CD into it, and then we'll install the bad words package. From there, we can export a Cloud function that runs every time a new document is created in the messages collection, that'll give us access to the message text, which we can then check for profanity. If there is profanity, then we'll clean the text and then ban the user for life, when we're done, we can deploy the function by running Firebase deploy only functions. Congratulations. You just built a full stack chat app with React and Firebase. It's secure, flexible, scales infinitely in the cloud, and like any good social app, it enforces community guidelines. I'm gonna go ahead and wrap things up there. If this video helped you, please like and subscribe. And in the near future, I'll be working on a full React Firebase course. It'll be available to pro members. And if you have any ideas, please feel free to leave them in the comments or let me know on our Slack channel. Thanks for watching and I will see you in the next one.
The speakers discuss building a real time chat app using React Hooks and security logic, as well as building a single group chat room and using native code in Firwork IO. They also explain the process of creating a chat room, including importation of necessary resources and setting up a web app. The use authorization state hook and the useflow process for signing in and chat room are also discussed, along with the use of a Google denies account and a code component to sign in and chat. The speakers also explain how to use the React UI to display chat messages and differentiate between messages sent and received, as well as the use state hook and the addition of a photo URL. They conclude by offering a full React Guinea course and encouraging viewers to like and subscribe.