 Hello everyone, welcome to my full stack React chat app course in which I'm going to be building a chat app from the ground up using Chakra UI, Firebase, as well as Next.js. So first I'm going to show you a demo of what we're going to be building at the end of this course, as well as I want to mention that the code for all of the videos is going to be linked in the description. So it's going to be a GitHub site. You can just go and check out the code anytime you want to. So on the left hand side, I'm going to sign in with Albert Einstein. And on the right hand side, I'm going to sign in with Max Planck. So you can see that we're using Google authentication that will be provided by Firebase. I can start a new chat here with Planck. I just have to type in the email and instantly we can just send a message. Hi, hello. How do you do? And I can click on Einstein's in the sidebar here and you can see the chat shows up and say, I'm doing fine. Thank you. You can see it appears in both screens. And I can even say, this is a really, really long message. So you can read it. You can see it appears in real time. So we're doing this using Firebase. I can show you the Firestore console here. I can refresh this and you can see how it works in the back end. So we're going to have a collection in Firestore called Chats. And then inside, we're going to have a document which has a randomly generated ID. And inside of this document, we're going to have the list of users who are involved in this chat. And then we're going to have a sub collection called Messages, which stores all of the messages called documents. So each message is actually a document inside of Cloud Firestore. You can see that we have the sender, we have the text itself, and we have the time step of when the message was sent. And right now we have three chats here. So there are three documents in this Messages sub collection. I can add a fourth chat. And you can see the fourth chat appears here. And you can see the text and time step. So this is pretty much how the Firebase back end works as well as how the front end looks like. And in the next video, we're just going to start building the app itself. Hello, everyone. In this video, we're going to go through the steps to set up our development environment so we can start working on our chat app. So the first thing I'm going to do is create a folder called chat app. Let's go into the folder and go to our terminal and CD into the chat app and run yarn create next dash app and dot. So this dot here means that we're going to create a next app template in this current directory. And I'm just going to let this run for a few minutes. And it seems like the command is done running. So I'm going to go and right click and open this with VS code and drag the window to the right monitor. Wait, there we go. And I'm going to run a terminal window here and just install Chakra UI. So right now I'm just going to go over to the Chakra UI documentation site and copy this command here and paste it inside of our terminal and let that run. So this line here will install Chakra UI and all of the components that's needed. And we'll go to the pages directory in the meantime and get rid of all of the junk that we don't need here. So here I don't need the default next.js template. I'm just going to get rid of that. I also do not need the styles and image imports here. So let me get rid of that as well. I'm going to go to app.js and get rid of this global styles because we don't need the default styles that next.js provides. And just nice, the Chakra UI components are done installing. And that's it for this video. In the next video, we're going to create our login component based on our sample site. So this I'm going to just log out here. So this screen right here, this is the login screen. We'll be doing this in the next video. Hello, everyone. In this video, we're going to be creating this login component that you see right here. And I'm first going to start yarn dev to start a development server here in VS Code. I'm going to refresh my localhost 3000 and see that we get an error. So I think we have to go to index.js here and get rid of this class name because we're using styles like container, but we're not importing the styles. So let's just get rid of that and refresh and see if we still get any errors. So we don't. So the first thing I'm going to do is go to my root directory and create a folder called components. And let's create login.js and let's export default function login. And let's just return login for now. So I'm going to go and add login inside of underscore app.js. And the reason why I'm not creating a dedicated route or URL for this login component is because I want the user to see this login component no matter what URL they are on. And no matter what page they are on, as long as they're not authenticated, right? So I just want to show this login page no matter where they are in the site. So instead of just returning component like that, I'm just going to return login. Let's import that login backslash. All right. So this is in the future, we're going to add like an if else statement to say if the user is authenticated, then you're going to return the component or else we're just going to return login if the user is not authenticated. So let's we see the login here, which is working, which is nice. So the next thing I'm going to do here is I'm going to change this to some brackets and let's add like head. So head is something that we're going to import from next because you see that we have if I take this browser here and I expand this, you're going to see that we have localhost colon 3000 as our title and that's not just that's just that looks ugly. So I'm just going to do title here and says login and let's save that and you can see now it says login. So we're no longer having that ugly localhost 3000 thingy that's going on there. All right. So now that's done. The next thing I'm going to do is I'm going to get chat icon here and paste it inside of our code. So chat icon is actually an icon from Chakra UI, Chakra UI icons. Basically is the icon that you see here, this white icon. And we're going to have to import that from Chakra UI slash icons, but we have to first install Chakra UI slash icons. So I'm going to go look for using Chakra UI icons there and run the yarn installation command. Let's stop the server for now and let's install Chakra UI slash icons. I'm going to show you the chat icon. This is how it looks like. So this is the chat icon here that I was talking about. I'm going to go back to our local host and let's yarn depth again and let's import chat icon. So import chat icon. All right. So now I can save this and I actually need to wrap everything in a react fragment, which is what I'm going to do and let's space it out nicely. All right. Let's save this and we are going to see nothing because the color is white. I can change this to black and you see the chat icon right there. I'm just going to change this back to white because I'm going to encompass this chat icon in a box. Let's do box and we have to import box. So let's import box from Chakra UI and let's give the box a background color. So we can see our chat icon, which is white right now. Let's add a background color of like blue. Maybe we give it a strength of 5000 and right now we don't see anything and that's to be expected because if I go and close this, go back to our app.js and the login component here is actually not encompassed by the Chakra provider component. So the Chakra provider component is something that is very easy to forget. So we have to import the Chakra provider. Is it not going to show up? All right. So maybe I should just do like Chakra provider and VS code will import that for me and let's move the login inside of the provider. Let's save this and there we go. Now we see our box. So don't forget to add the Chakra provider every time you are creating a new component inside of underscore app.js. So with that, I'm going to go ahead and do the width should be fit content. So it doesn't expand to the full width. So we're going to be building something like this. I'm just not going to do the gradient because gradients are kind of complicated. I'm just going to use a solid background of blue and let's see what else do we need. All right. So we're going to need like some padding because right now it's just stuck, you know, to the edges of the icon. So let's give it a padding of five, much nicer. And if we look at our example, we actually want rounded corners, right? And in Chakra UI, there's something called rounded that we can use and we can set a size. We can like md for medium as m for small, it can even go XL or even 3 XL for really rounded corners. And you can see that's our rounded corner. And that's pretty much it for our box and our chat icon. So the next thing I'm going to do is I'm going to add a button down here. Let's add a button that says sign in with Google. That's what it says, right? So in the example, you can see signing with Google. That's what it says. And we can give this box shadow to make it look nicer. I'm going to give it a medium box shadow. You can see that the box shadow comes up now. I'm also going to give this some box shadows. So I'm going to just give it box shadow of medium again in the box. All right. So let's refresh this and it looks nice. All right. So now that we have these two components, we want to center this in the middle of the screen, just like how we're doing it here. We want to center this so it looks nicer. So to center these two elements, I'm going to import something from Chakra called center. And we can actually just do it here, right here. Center and let's move everything into this center component. And let's space out nicely. All right. So then you can see that it's now centered horizontally, but it's not centered vertically. And to do that, I'm just going to give this center component a height of 100% view height. And this should now be centered in the middle of the screen. All right. But now it's actually aligned horizontally. It's stacked horizontally. We don't want that. We want it to be vertical just like this. So how we can do that is by importing stack from Chakra UI. And we can go ahead and make a stack and put everything in that stack like this. And if you guys don't know any of the things I'm doing can go to the Chakra UI documentation, it's actually really good. And you can just read up like, what is BG color? What is P? P is padding. You can just find everything in documentation. So now our stack is working nicely. It's kind of stacked vertically now, but it's aligned on the left hand side, which is not what I want. I want it to be aligned centered. So I can just say align equals to center. And it's going to be centered like that, which is nice. And I'm actually going to give this stack some background color because as you can see, we have like this gray background color in our example. Let's give it a background color gray. Let's set it to like 600. And there we go. We still need some padding though, because let's give it a padding of 16. And that will look much nicer. And of course, we want it to be rounded just like the icon. Give it 3XL. And that will be rounded. And what else do we need? So we need spacing in between these two components because they're just stuck together right now. I'm going to give it spacing of 12 inside of this stack attribute. So now that looks much nicer. I'm going to give it a box shadow as well. Box shadow. Let's just give it 3XL again. Just actually, we're just going to give it MD or large, maybe. Yeah, let's just give it a large box shadow. And this looks pretty similar. It doesn't look 100% the same because we have different gradients. We just use a solid color. But this is pretty much it. We've officially completed our login component. And this looks nice. All that we need to do right now is implement the functionality to this sign in with Google button. But we're going to do that the next time after we're done with all of the interface, all of the chakra UI stuff, right? In the next video, we're going to be doing the layout of the chat once we sign in. So we're going to sign in here in the demo. And we're going to have a layout like this. So this layout is what we're going to be creating in the next video. We're going to have a sidebar. We're going to have a chat area. And then we're going to have, inside of the chat bar, we're going to have like the avatar, the name, the logout button, the new chat and everything there. Hello, everyone. In today's video, we'll be building the sidebar of our chat application in React. So this is how the chat bar would look like. There's an avatar, some text, a logout button, a new chat button and a whole list of chats or contacts that you can message. So this is our current project and how it looks like. It's the login component from our previous video. I'm just going to go over to our app.js here and just take out this login component right here. And I'm just going to give sidebar for now. Temporarily, while we're working on the sidebar, I'm just going to do this. And I'm going to go to the components folder and create sidebar.js. Next, export default sidebar. Okay. And I'm just going to return sidebar as a start. I forgot the function here. Let's refresh this and see if it works. Sidebar is not defined. So we have to import sidebar from components and it should work now. All right. So this is all good. We're just going to go to the sidebar component now and start building our actual sidebar. So the first thing I'm going to do is going to return a flex component, which is something that you're going to import from Chakra UI slash layout. And in this flex component, it's going to be the parent container for our sidebar. So to make things easier while we are developing this, I'm just going to give it a background color so you can visualize what's actually going on. Let's give it a light blue and you can see that there's no sidebar. There's nothing right now because we haven't given it width. So I'm going to give it a width of 300 pixels. We still see nothing because there's no height. So I'm just going to give it a height of 100% view height. And now we should see our sidebar. So if I take this to full screen, you can see the sidebars at the side like that. Next thing I'm going to do is I'm going to give give it some borders. So I'm going to give border end of one pixel and make it a solid border. And I'm going to have the border color be gray. So gray 200. And you can't really see the border right now. But if I get rid of the blue background, you can see that there's the actual border, this thin line right here. All right, so let's get our color back for easier visualization. The next thing I'm going to do is I'm going to create flex items inside of this parent container. So I'm going to do flex. And so let's look at what we're building here. The first thing we're going to build is this top barrier right here that has the avatar and the username as well as the logout button. So I'm going to give this flex item a height of about let's make it 81 pixels. And let's give it background color as well so that we can visualize it. So red of 100 should look like pink. And we don't see anything right now, do we? So I don't think it has a width, which means I'm going to just give it a hundred percent width so that it fills the whole width of the parent container, which has like 300 pixels. All right, so it's looking good right now. I can go full screen and you can see how that actually looks like. So that's pretty much it for the layout of the sidebar. Now all that's left for us to do is fill in the items, the contents inside of the sidebar. So the first thing I'm going to do is deal with this profile picture. So to do the profile picture, I'm just going to import the avatar component from Chakra UI and I'm going to self close that. So I'm just going to give it a dummy source so it gives us the default profile picture. And now that it's actually stuck on top of the screen and I don't want that I want it to be centered. So I can do align items. But because we're using Chakra UI, we don't have to type align items. We can just do align, which is the short form for align items. And I can do center. It's going to be centered like that, which is nice. I'm also going to do the log out button right now, which is the button you see right here on the right hand side. So let's give it an icon button from Chakra UI as well. So then an icon button needs an icon, which is what I'm going to provide and I'm going to get the icons from Chakra UI icons. But I don't think there's a suitable icon here in this library and I don't want to install a brand new icon library just for this single icon. So I'm just going to pick this arrow left icon, which is not that suitable, but we'll just have to make do. So let's use that icon from Chakra. So let's import that and let's refresh. You can see that the icon button shows up, but it's a bit too huge, too large. So let's set the size to be small as well. I'm going to give it is round to make it rounded. And let's save this. You can see it's now rounded and slightly smaller, which is nice, but I want it to be on the right hand side. So the cheapest and dirtiest way to do that would be to just use something called justify content. We can justify it to be space between and that will go to the far right hand side. We can also combine this to be on the same line because it's the same group. I'm going to give it padding of three and save. And the next thing I'm going to do is add a text here so that we can display the username, which is something we're going to import from Chakra UI. Let's just give it a dummy username for now. Save that. Okay, so this is all right, but it's kind of in the middle. And if I look at our sidebar here, we don't want the text to be in the middle. We want it to be slightly to the left. So it's grouped with the avatar. So I can accomplish that by using another flex container here. Let's move those two elements in. And let's give this flex a line of center so the text isn't like skewed to the top much better. Let's give this avatar a margin and of three maybe. All right, the next thing I'm going to do is add this new chat button right here. So I'm going to comment out the red and the blue so you won't see the red and blue. And we're going to have to add the border here. Let's just give it border bottom equals to one pixel solid and give it a similar border color of gray 200 and paste. So we get our border now. And I'm also going to add like the new chat button. So I'm going to have to import that from button from at chakra UI slash react. There we go. And let's come down here below this flex group because this flex group is, if I'm not wrong, yeah, this flex group is for this top bar right there. So let's just add a button down here that says new chat. And we should see that appear, but it's going to appear at the side because this is display flex. So we can go to parent flex container and just go direction equals to column and jump here down there. I'm also going to give this button. Let's give this button a margin of five units as well as padding. I'm going to give it a padding of four and you should see that look much nicer right now. So now if I go back to my reference, you can see that we're going to have to do the individual chats here that you can click on and go to the specific chats. So I'm going to wrap everything in a flex container because you can see we're going to have multiple elements, which is an avatar and as well as a text. So let's add the avatar and avatar is a self closing tag. We can also give it a dummy source and see how that looks like right now. All right. So we're going to give this flex a hover equals to background of gray $100. So if I hover my mouse, you can see it becomes gray. And I want to also make the mouse, the cursor, so cursor to be pointer because if you see right now my mouse hovers and it doesn't look like something clickable because the mouse is still a normal cursor. But if I save this and this becomes a pointer when I hover on top of it. So let's also add like text that says user at gmail.com for now. And there's the text. So we might also want to give this flex container an align of center to center the items vertically. And there we go. And let's give this avatar some margins. So margin and equals to three units. Whoops. What did I do? Three units that looks much better. We also want to give this flex container some padding because right now it looks like when I'm hovering on top of it looks like it's just restricted by that avatar's height. So let's give it a padding of let's see how much padding should we give. Maybe we should give like three. So at this stage, you can already see that this component actually feels quite clickable. It looks like something that you can click because when I hover my mouse becomes a pointer and the background changes. But the thing is it's not done yet. It may look done but if I duplicate this multiple times and save it you can see that it goes way past the screen and we're going to scroll the entire page if we have too many users and that's probably most likely going to happen in a real application app. So I'm just going to scroll up and get rid of all of these. Let's fix this. We don't want the whole page to scroll. We just want this sidebar, this panel here to scroll. So how I can fix that is I'm first going to take this out and put it in its own component. So const chat equals to an arrow function. Let's return, let's return this component like this and there we go. And then here I'm just going to put like the chat component. So to fix this we're going to use flex again and let's wrap this component in the flex container. So what we're going to do with this flex is give it an overflow x of scroll. So if I put this then it becomes that. I'm going to just put a lot of chats down here to see how it looks like and you can see that it's starting to stack horizontally which is not what we want. So we can give this flex direction of column to make it stack vertically. So now the scroll is working exactly as we wanted to. It's just scrolling this small section here and not the entire page but the scroll bar is still kind of jarring and we can get rid of the scroll bar by using the scroll bar with CSS property and this allows us to set the scroll bar scroll bar width to none. But the thing is we can't just do like scroll bar width equals to none like this because this is not a is this is not a valid prop to the flex chakra UI component. So instead we can use this thing called the sx prop provided by chakra UI to allow us to directly override a CSS property that may not be included as one of the props of the component. So the way we can do that is do sx equals to an object that has scroll bar width and we can set that to none. And once I save you can see instantly we get rid of the scroll bars but we can still scroll and with that we're pretty much done with the sidebar. I can go to full screen and you can see it works just the same. So in the next video we're going to be taking a look at how we can build out the skeleton structure for this right hand side here the chat page. Hello everyone in today's chapter we'll be coding the UI for the chat area that you see here. So we have a top bar we have some chat area as well as the bottom bar. But before I start doing this it's worth noting the URL it's basically the domain name slash chat slash whatever ID the current chat is. So to do that I'm going to go to my pages here and create a folder called chat and to collect the URL the dynamic URL ID here what we can do is we can go ahead and add square brackets and an ID.js. So this is basically a next.js thing in which we can use to collect the dynamic URL here. All right so let's export default function chat here let's spell that properly and let's return a chat message just for now. So now I should just go here and type slash chat slash some random ID and we're going to get the same thing here we're not going to get our chat and that's because in our app.js we have we are returning the sidebar component no matter what the route is. So to fix that we can just render we can just return the component from the props that we're getting from next.js instead of just hard coding the sidebar in and now we should see the chat appear and there's one thing I want to fix here is that in the chat area we still want the sidebar to show up even though we're in the chat area so what we can do is we can go and import the sidebar and we can return the sidebar here so let's return I'm going to wrap everything in the flex container and let's put like the sidebar here there we go so now we have our sidebar and there's one thing I want to fix is that in the sidebar component we have our height of 100 view height 100% view height here in the sidebar so instead of putting putting it here in sidebar component I'm going to instead put it here in the parent component that which is the flex component so let's place that here and now we should see that everything works and the next thing we're going to do is the top bar here so you see this top bar let's make that so to make the top bar we're first going to have to partition this page into two separate sections because we're going to have the left section for the sidebar the right section for the chat area so I'm going to go here and make another flex container just right underneath the sidebar and we're going to give this container a background color so it's easier to see what we're doing so blue of 100 and now we don't see anything because there's the width of zero and also we have to specify the direction here in the parent flex container to be actually I don't think we need direction since we're going we're doing that horizontally so I just have to specify like a width so to do a width I'm just going to make it flex one so it can automatically grow to fill the entire width so now we have that all right that's cool so now that we have that we can just get rid of bright ground color because we know that it's working just as intended and inside of this flex container we're going to have three other flex containers which is the one for top bar one for middle chat area and one for the bottom bar so I'm first going to work on the top bar we can actually just do like top bar which is a component and we can make that component outside here so const top bar equals to an arrow function that returns a flex container that contains an avatar and some heading so let's just do avatar there we go and you can have a dummy source for now let's see how that looks like we are also going to have to style this flex container so we can give it like a background of gray strength of hundred and that doesn't look right so that's doing because it's having a hundred percent height we can specify what what height we're going to want which is 81 pixels if I'm not wrong that's the height of the the bar on the right hand side as well and then let's have a width of a hundred percent see how that looks all right that's much nicer and then let's align everything to the center so align center so the avatar goes to the middle I'm actually not sure why the height of these two top bars here aren't lining up they're supposed to be 81 pixels in height and I'm going to go over to the sidebars top bar and 81 pixels as well so that's weird I'm going to go and use our web development tools in the browser that's so this is supposed to be 81 pixels but it kind of looks weird something weird is going on here so it's set to shrink so the item was set to shrink and it has a flex string of one so I'm I'm thinking it's some kind of issue with the flex flex box so we have one parent container we have one flex container and one button element in the final flex container here so I think this is oh we forgot the flex one so we have like three containers so one for the top bar one for the new chat button and the one for the scrollable part here and we forgot to let that last container grow on its own using flex one so now we have flex one it should be fixed so if you guys aren't sure about all this flex box stuff you can just go to csstricks.com and they have like a really good website and I'm pretty sure flex grow is here as well so like flex grow yeah flex grow is here and we have flex one as well so basically what I'm doing is I'm using flex grow to expand to let the heights of those containers expand on its own and with that fixed you can continue working on our top bar so I'm just going to give this a padding of five so that it's not stuck to the left hand side of that border and we can also let's see what else we need the heading of course so let's do it like a heading and let's import that the heading should say like user at gmail.com and see if it matches up so I think we can like specify the size and we can give the size of large so lg and that's a bit smaller we can give this avatar a margin end of three so that's not stuck you can actually just use margin left as well or margin like right and it works but the benefits using margin end is that this is more friendly to for those kind of right to left or left to right screens so using start and instead of left and right so the top bar is now done and we can go and work on the bottom bar so I'm going to have like a bottom bar maybe you can make our own component for that as well so like const of bottom bar equals to an arrow function let's return like like bottom bar for now let's go and add that here so top bar and bottom bar in our flex container and our bottom bar is going to appear on the right hand side which is not what we want so we can give a direction of column to this flex container and it should be stacked like that we can also give this bottom bar like a let's just make the flex container here and give it a background color so it's easier for us to style so let's do flex let's give it a background color of like blue hundred so we don't see that right now so we might as well give it a height of like some arbitrary value so that's our bottom bar and we have to align our bottom bar in the bottom of the screen and we can do that by adding like at the chat area in the middle which is going to be a flex container and let's just give it a flex one so it will grow so now we should have it separated so we have a top bar we have a flex container and we have a bottom bar so top bottom middle and bottom so three sections I'm just going to make this all in one line for now so it's easier for us it's easier on the eyes so let's do that all right so one two and then three sections so now let's continue working on the bottom bar here inside of the bottom bar I'm going to have like an input from chakra and I can actually get rid of the height now and get rid of background color as well so that's our input we can give this input a few few props like placeholder equal to type a message dot dot and that should show up like that we also want to give this flex container like a padding because we don't want an input to be stuck to the edges of the screen so let's have a padding of three maybe that's much nicer so this will definitely work because you can type messages here and you can click on the button to send the messages but what won't work is if you hit enter like you normally would in normal chat apps because this is just a naked input and it's not part of any forms and it doesn't have a submit button so when you hit enter each channel doesn't know what to do because it's not a form so to fix that we can add a form here using form control from chakra ui and of course we still need a submit button even though if we want to hide it we can just use like hidden but it still has to be a type of submit because it's part of the form and let's auto close let's actually just close this button and like hit like right submit it's not going to show up anyway because it's a type of hidden and the thing is if i try to type something here let's type something uh let's see if it shows up it doesn't show up so basically sometimes the auto complete shows up so you can use auto complete equals to off to turn off the auto complete now what you could do next is you could go ahead and add an icon button to the side of this sidebar but i'm not going to do that because it's going to make this video crazy long all right so it's now time to work on the chat bubbles so let's go and look for the parent container to contain all the chat bubbles and make our very first chat bubble inside of this container so one thing we're going to do is we're going to create a flex container to contain this first message and we're going to have a text in here that says um this is a dummy message it looks like we have to import this from chakra ui so let's import that and let's give this flex a background color of blue of a hundred so now this is what you see but the thing is we're going to have multiple uh components to contain these messages and that's going to look like this which is not what we want because we want it to be vertically stacked so we can do direction equals to column here in the parent container and they will be vertically stacked which is very nice and of course we can go ahead and style these and give it like a width of fit content so it doesn't extend to the edge of the screen and we're going to give it a min width as well so just in case we have like very short messages because let me just demonstrate let me just like make this an a you can see that the width is going to be so small so we can make a min width property and give it like a hundred pixels so now we have min width and what else we want to make it rounded of course so we can give it like a border radius of large so it's now rounded at the corners and you can give it a padding of three and let's make it spaced out a bit more so let's give it a margin of one so that already looks much much nicer and the thing is we're just making this for sent message we want another type of styling for a received message let's say this message here is a received message so we can give it a different color first green 100 and let's align to the right side so we can do align self equals to flex and so that will go to the right side and if you don't know what this property is you can go to the css tricks that i've mentioned earlier and just look at this property called align self now there are a few things i want to do to the parent container of these chat messages so the first thing i want to do is give it a padding of top to become four so that it's not stuck to the top bar there and you're going to give it a margin x of maybe five so it's not stuck to the sides so that's much better and another thing i want to show you is that if i clone these chat messages a lot of times you can see that the whole page starts scroll again and this is not what we want so what we can do is go back and look for the parent container here let's give it a overflow x to be scroll and that looks much better because you can see now that's how you're scrolling and we also want to get rid of the scroll bars using the sx prop so scroll bar width of none and this is very exciting because we're now done with all of the styling and chakra ui stuff so in the next video we're going to start working on the actual functionality of this site so the firebase authentication cloud storage and everything like that in this chapter we'll be going over how to implement firebase authentication in our chat app so i'm going to go to the root of our app and we're going to get a blank page because in index.js we have the head but we have no content which is why i'm going to add the sidebar here sidebar and let's save so now we should see the sidebar appear in our main page and the next thing we're going to do is check if the user is authenticated because if the user isn't then we should display the login component which is what we've done previously right here this is the login component so before i do anything to the login component i'm first going to create a firebase project and link that to this react application so i'm going to head over to firebase console and let's create a new project we can call this chat app then let's accept the firebase terms hit continue we don't need google analytics for this project and we're going to give it some time to load here and our project is now ready so i'm going to hit continue and it will bring us to the console all right so now we have a brand new project we're going to create a new web app and let's register the app as um react maybe reactjs and then we can register the app like this and we're going to have to add the firebase SDK so i already know what's going to ask us to do so i'm going to go over to my terminal here and let's uh let's go and stop the development server and let's yarn add firebase so this will install the firebase SDK to our project and if i go back to the browser you can see it's already going to ask us to do that using npm and i'm going to copy this entire thing and go put that in a file called firebaseconfig.js in my root directory let's just paste that there so if you can see here it asks us to add SDKs for specific firebase products that we want to use so i'm just going to delete this and let's import getauth from firebase slash auth and let us come down here and do const auth equals to getauth and we can export auth so we're going to import this auth object from other files later on in order to work with this authentication handle and then i'm going to go back to my console here and let's continue to the console so first of all let us go to um authentication right here and let us get started all right so as you can see here we have a lot of different methods we can let our users sign into our app we can use email password authentication we can use microsoft authentication facebook even github but in this project let's just use google so i'm going to click google and enable that and what this does is it allows you to authenticate your users using their google account so now that google is enabled i'm going to go ahead and install react firebase hooks which is a way for us to implement authentication using pre-built hooks in this npm package of course you can just go ahead and read the documentation and do it manually using the firebase docs but instead i'm just going to install react firebase hooks because it's easier and faster sometimes so let's copy that and go to our terminal here let's paste and all right and then i'm going to go and open up the documentation so let's see authentication hooks that's what i want all right so let's look at the documentation here we have this hook called use auth state and we can import that using the statement which i'm just going to copy and let's actually just yarn dev and start our server right now and let's go to app.js and import that so i'm going to import use auth state and let's go back to the documentation and copy this so let's paste that here so as you can see use auth state takes in auth and options which we don't really have any options right now so i can just get rid of that and then it'll return user loading an error so we have to pass auth or it's going to throw us an error so let's import auth from dot slash firebase dot dot slash firebase config so remember where we exported the auth handle so we're just going to import that and chuck that in the use auth state parameters right now and then now that we have access to the user loading an error object so what we can do is we can say if loading so if loading is true we can add a spinner here so that we don't let the user access the website when everything's still loading so i'm going to do chakra provider because you always want to wrap the entire page inside of a chakra provider element and let me do something from uh chakra ui slash react which is spinner so i'm going to do a spinner size let's just let's just see how spinner looks like right so instead of if loading i'm just going to say if true so that we can see it right now let's go and refresh this and see if there's a spinner so there's no spinner of course i forgot to write return and you have to return this like that and let's so we see the spinner right now and it's stuck to the top left so i forgot to import center and let's do center and put a spinner inside of that center element which will give view height of 100 percent view height let's see now so it's not in the center but it's kind of small so what we can do is we can give it a size of xl yeah so that looks way better all right so now we can change this from if true to if loading and let's go back and refresh the page and let's see so you see for a moment there the spinner showed up because it was loading and right after that it's just switched back to the normal component and that's good so now we can work on the user so if the user is not signed in what we're going to do is we're going to return the login component right and then we have to remember to wrap that in a chakra provider or else the styles are just not going to show up there we go so now we have our login component here but i still need to implement functionality to this button right here because if i click on it it it does nothing right now and that's because in my button component i don't have this thing called on click which i'll add right now and let's add in an arrow function that we'll populate later so the next thing we'll do is go to firebase react firebase hooks the documentation side and let's look for use sign in with google so this hook is the hook that we're going to use and i'm just going to copy this line and paste it just right here let's paste it right here and then we're going to have to import that so import use sign in with google there and let's take a look at this hook this hook takes in an auth handle which we have to import from the firebase config.js file so import auth and it returns sign in with google user loading an error so if we look at the documentation you can see that sign in with google is actually a function that you can call that takes into parameters which is the scope and the custom oauth parameters but we're going to deal with that later so let's first call this function here sign in with google inside of this arrow function and i'm going to go back to our application here let's refresh this just to be safe and let's click on this button and it shows us the google authentication page which i can gladly just click and once we're in it should change to the sidebar which is much better right now all right so we're now signed in so now what now of course we're going to do the logout functionality so this button right here is going to do the logout functions so let's go back to our sidebar here and look for that button that's an icon button and this right here this icon button it can add like an on click and give it an arrow function again so how do you sign out users in google firebase authentication if you look at the documentation right here there's something called sign out which is something you can import from firebase slash oauth which is what i'm going to do i'm just going to take this copy it and paste it right here except for the fact that we don't need to import get off here so we just need sign out and we can just write sign out here sign out okay so let's refresh this page and now the moment i hit this button we should be signed out and it gives us an error because we have to sign out and pass it an oauth handle i think which we are it which we will import from firebase config and let's save that let's refresh this let's try to sign out again so i hit that so yeah it works all right so one small issue that we're going to fix before moving on to the next section is that when i click this button this window shows up but before we get to choose which account to log in with it's just going to log us in with the default account and that is bad because we don't get to choose and switch accounts so i'm just going to log out here and we're going to use this thing called custom oauth parameters to modify the functionality of this firebase hook so if i go back to my code here i can provide some scopes and some custom oauth parameters which i'm going to just do right now let's go to our login here so the first argument is the scopes which we don't want to change and that's a string so i'm just going to leave it as an empty string and the next parameter is some custom oauth parameters which is an object and what do we put in here that depends on what the documentation says so we can go to the google website and go to the documentation and you can see there's an oauth parameter called prompt and this prompt lets you choose the different types of prompts so this select account is the one that we're interested in because this will allow our user to select multiple different accounts when logging in so let's just copy prompt let's just do that as a key and the value will be select account and that will be a string all right so now that we have saved that we can go and refresh our page and let's click on sign in with google so this time we should be able to select our account and login or use a different account totally and now i'm realizing something and that is our scroll is broken again because we imported the sidebar into index.js and that's a totally different file so i'm just going to fix that by giving it a box and putting the sidebar in a box which has a height of 100% view height and let's see if that fixed the issue and it doesn't okay so i have to go to the sidebar here and let's restrain the height to 100% of the parent containers height so that should fix it and yeah it's fixed in previous chapters we've gone over how to build a UI for the sidebar that we have here and in this chapter we're going to go over the functionality and how to implement the functionality into the sidebar instead of just having hard coded values using firestore so i'm going to sign in with two different tabs here one using Einstein's account and one using max's account and what you're going to see is that we're going to have a sidebar here and the same sidebar right here and that's because all of the values are hard coded so let's go ahead and change that but before i do that i actually want to do some housekeeping here because you can see we have create next app here as the title of the tab and i want to change that real quick so let's go to index.js right here we're going to just change this to chat app and we should see it become chat app i'm also going to go to another page that we have which is slash chat slash whatever the id is and you're going to see localhost colon 3000 slash chat slash whatever so let's change that inside of our chat page and id.js so here we're going to import a head from next slash head and let's go to the return here and just add the head and to do that i'm just going to add it in this flex container here so let's do head and let's make a title let's just call it chat app all right okay so that's fixed now let's worry about the sidebar and the profile picture here so first thing i'm going to do is go to react by base hooks documentation go to authentication hooks again and let's copy use author state so i'm going to bring this over to our application in the sidebar component and let's import this like that and i'm going to go down to use author state here and let us look for this line here bring it into our code as well inside of the sidebar component and we actually don't need loading an error so i'm just going to get rid of that so now we have the user and also we don't need options so i'll just get rid of that as well author is going to be imported from Firebase config so now we have our user object and that's really that's really good because we can go to our text here and just replace this with the user dot display name and in avatar instead of just an empty source you can just do user dot profile actually is i think photo url that's right okay now let's go back to our firefox here let's refresh this you can see now that instead of just having the hard coded value of albinestine and that default avatar in both tabs i actually have different names now so this is actually going to be fetching the data from the firebase back and itself all right so we're now done with authentication and we can move on to using firestore to store all of our chats here in the sidebar so to do that i'm going to show you the system that we're going to use in this project so here i have two chats here and the moment i click on the chat next jess we'll use next jess router to redirect us to the url of slash chat slash the id and that is basically going to give us access to that dynamic id parameter that we added here in our file structure so here uh this id is going to be the id of the document of the chat so in our firestore database we're going to have this structure right here which is a collection of chats and in this collection we're going to have multiple documents and each document represents a single chat so here i have two chats so we'll have two documents and inside of that document we're going to have a list of users which is all of the users that are involved in this chat and also we're going to have messages which is going to be a sub collection of all of the messages so we're going to deal with this messages collection sub collection later on so right now we just need to focus on the users here because we just need to know which users are involved in this chat so that we can list out all of the user names in the sidebar so i can actually show you how it looks like in the firebase console so we're going to have like chats which is a collection which contains all of the chats so right now we have two chats like this right and in this chat we're going to have a list of users of all of the users involved and we're going to have messages which is a sub collection that contains all of the details of the messages all right so let's get work and add the firestore SDK to our project so i'm going to go to firebase config and let's clone that and instead of get off we're going to get firestore from firebase slash firestore and then you're going to do const db equals to get firestore and let's export that as well i'm also going to go to our console and create a database in cloud firestore section let's start in test mode and let's hit next we can change you can just leave this or whatever you want you can enable that and let it provision for a bit all right so the provisioning is now done i'm going to start a new collection by the name of chats and here i'm going to refer to our structure here so we have a collection of chats and we're going to have individual documents that store the information for each individual chat so i'm going to just generate an automatic id and we're going to have users which is going to be an array so this user's array will store all of the users that are involved in this chat so let's get our first user and copy the email and paste it here let's add another user so we have two users now i'm going to hit save and we should see it appear right here so there's our document now what i'm going to do is go and use cloud firestore hooks from react firebase hooks and just import use collection and let's go to our vs code and sidebar and let's import this use collection hook and we can import this line as well so that we can copy and paste that in our sidebar component i'm going to get rid of the options right here because we don't have any options right now and for query we're going to query for a collection by the name of chats so i'm going to have to import that collection reference from firebase slash firestore let's do collection and we're going to target the collection by the name of chats and i think for the first argument we're going to have to provide the db handle which we have to import from our our firebase config like that okay so now we're going to get our snapshot and we can console log the snapshot to see what it looks like let's see that in action so i'm going to open up my console here and let's zoom in a little so you can see here we have our snapshot object which isn't that useful for us because we still need to get the data from the documents inside of this snapshot so you see docs here this is going to be an array of all of documents that is inside of this snapshot so what we can do is we can do snapshot dot docs and we can map through each individual document and extract the data like that so let's go ahead and do constant chats equals to snapshot dot docs dot map and we can extract the data inside of this map function but one thing you note is that in my console you can see that sometimes the snapshot returns undefined and that's when firebase is still querying the data so if you do undefined dot docs dot map it's going to give you an error because undefined doesn't have the property of docs right so we can use the question mark operator here to say that only if snapshot is defined then we'll do this so in the map function we're going to get a doc and then we're going to just return we're going to return an object that has id of doc dot id and we're going to use the spread operator to do doc dot data and spread that into this object that we have right now so this step is actually quite important to include the id of the documents because later on inside of our sidebar when we're going to do like when we're going to click on these individual chats you're going to have to redirect the user to the id inside of the url and so that's why we need to be sure to extract the id as well instead of just getting the document data all right so now we can console not log chats and see what we get in the console so let's go ahead and refresh this and we should get an array of a single object because that's what we have here a single document and in this document you're going to have the id of the document as well as the users so i'm going to create another document here let's add another document and we can do actually users and it's going to be array let's do test at gmail.com and let's add another user which is our current user let's save that so now when i refresh this i should get two documents in this array all right so in this array we're going to have two documents the first document is between test and einstein and the next document is between einstein and plank all right so we can actually replace our chats here with the data that we're getting from firestore so i'll delete all but one chat and inside of the chat component instead of returning just a single chat we're going to return chats dot map and we'll map through each individual chat and return this component so let's cut that and let's paste it here with proper indentation like that and we're getting this error because missing keyprop for element in iterator so let's just give this key to the flex parent component i'll just do key equals to math dot random this is a very terrible way of assigning keys to elements when you're using dot map because sometimes map dot math dot random doesn't guarantee you a unique number but i'm just going to do that for convenience sake so we can just replace user at jim.com with chat dot users let's save that and see what we get in the browser let's refresh that and we get chats is not defined all right so we don't actually have access to the chats variable here because this is outside of our scope so we are going to have to just let's get rid of this console log and let's just paste the chat here and let's change this chat over to um a chat list function and wrap that in holy braces and instead of calling this capital letter chat i'm just going to do chat list like that and here i'm just going to add a question mark just in case chat is still undefined and let's go back to firefox and refresh and see if we do get the error still okay though we're not getting any errors right now this is still not what we really want because here in the sidebar we're getting all of the emails here including our own email which is not what we want so here in our code you can see that chat.users is what we're using and chat.users is an array of all the emails so i'm going to go ahead and solve this problem by creating a utility function called getotheremail.js and let's const get other email equals to an error function and we'll export default get other email so i'm actually going to take in two things in the arguments so i'm going to take in users which is the list that we had just now of the two users involved in the chat and also the current user which is the user object that we're getting from the use auth hook so let's return users sometimes users will be empty so i'll just add an extra question mark dot filter so we'll filter user and we'll see if the user is not equal to the current user now remember the current user is actually an object that we're getting from the use auth hook so this is not actually users email we need to access that email by using the dot email property and we'll get the first result and return that now let's head back over to our sidebar and i'm going to save this and import import get other email so here instead of just returning chat.users i'll return get other email and takes in the users the users list which is chat.users and of course our current user which is what we're getting from the use auth state hook let's save that and go back to our browser and see if the results are what we want so let's see test at gmail.com which is the opposite user as well as plank so this is working as intended but there's still a slight issue that i'm going to show you by creating a new document and let's make a new chat so we're going to have users and this has to be an array and let's say that we have a conversation between plank which is not our account our accounts Einstein and test at gmail.com so this conversation between these two people does not involve Einstein which is our current account right here so let me go ahead and save this document and let's go to our panel and you can see that we actually have two different plank contacts here and one of them is our chat with plank another one is the chat between plank and test which doesn't involve Albert Einstein so you can probably tell that this right here is a huge major security issue especially if this is a real chat app so one of the ways we can solve this is of course to use the firestore rules to secure which user has access to which data but i'm not going to do that in this project and instead i'm just going to use um javascript here and do a dot filter and we're going to filter the chat to make sure that chat has something to do with our user so users dot includes our current user dot email and this current user is the user that we are logged in s and let's just save this and refresh the page so right now you can see it works we only have test and one plank chat and if i go ahead and add a new document that has um users and let's do an array of like some some random user at gmail.com and another random user at gmail.com so this has nothing to do with Albert Einstein so i'm going to save that let's refresh this and we should not see that appear in our sidebar anymore and perfect now let's make it so that when i click on these chats it's going to redirect me to slash chat slash whatever id the chat is so i'm going to go to the code here and add on click so on click equals to an arrow function that runs a redirect function that we're going to make ourselves it doesn't exist yet and it's going to take in the chat dot id so let's go ahead and do const redirect and takes in an id and here we're going to have to use nextjs router to do this so let's import use router from next slash router and in here i'm actually going to have to use const router equals to use router which means i can't have this redirect function outside of my component so i have to bring it back in here because or else i won't have access to the router handle so let's do router dot push and then slash chat slash and let's format this to include the id this should be it so i'm going to save that and let's come here so when i click on this it's let's refresh this all right and let's go to localhost slash 3000 and let's click on one of these so i'm going to click on that and you can see it redirected us to slash chat slash whatever the id so that's perfect and i'm going to click on test and it's going to redirect us to different id as you can see in the url bar all right there's one thing left for us to do and that is this new chat button so i'm going to go and look for that button which is right here new chat and then let's do on click equals to an arrow function that we can call new chat and let's go and make that function up here so const new chat equals to so in here what i'm what i can do is i can do const input equals to a prompt so enter email of chat recipient and there we go and now let's go and see if it works so hit that all good all right okay and the next thing we're going to do is we're going to add doc add a new create a new document in our firestore collection here in the chat's collection so what we can do is we have to import add doc from firebase slash firestore so add doc and okay so in here we're going to just await because add doc is an api call so maybe we need async and await and that means when you add an async here and let's await add doc and the first argument is going to be the reference right here so we can call collection and pass in db and chats as usual then the next thing is the object which is the data object so data object is going to contain users and it's going to be an array so user dot email and input so user email is our own user our current user and an input is the new user the new email that we're going to get from the input all right save let's go and new chat let's say hello at gmail.com say okay and hello shows up here and just to make sure i'm going to go to the console and make sure that hello is here as well but we're not completely done with this yet because if i come here and i try to create a new chat with test.gmail.com again which already exists as you can see in the sidebar it's going to duplicate and that's not ideal so now we're going to have two records that has our conversation between Einstein and test so run one right here another one right here so let me just delete this document real quick let's start delete all right so to do that we're going to implement a few checks in our new chat here so we're going to write a function called chat exists and it's going to take in an email and it's going to compare this email with our current user's email and check if a record of that already exists in the chats snapshot so let's do chats dot find chat for each chat the criteria would be chat dot users dot includes user dot email this is our current user email as well as chat dot users dot includes the email that we're getting as the input here in this function then here we can just write a conditional here so if not chat dot exists which means if the chat doesn't exist only then it will proceed with this await so let's move the await in here and i'm going to take this opportunity as well to do a few more validations so i don't want to be able to create a new chat with myself so i'm going to make sure that input is not equal to our current user's email so now i should be able to go to my chat app and try to create a new chat with test at gmail.com which already exists that hit okay so nothing happens and it doesn't add a new record to the Firebase backend so that's good in this chapter we'll go ahead and finish up the last part of our course which is to make this chat and get the data from firestore so first thing i'm going to do is look at this id here in the url and get that data from within the code so i'm going to utilize this thing called router which is going to be imported from um from next slash router i believe all right and the next thing i'm going to do is go over to my chat component and do const router equals to use router and here i'm going to do const id which is something i'm going to extract from router.query and now i can console.log id and let's see what we get so refresh that and open up the console and we should see our id show up so there it is and then i'm going to go ahead and create some dummy messages in the back and the firebase console instead of having it be hard coded here so i'm going to follow this structure right here which is the messages sub collection and i'm going to go ahead and create that now so let's look at the id so the id of our chat is ex orp and it's right here ex orp and let's start a new collection we can call this collection messages and we're going to all generate this id for the first document in this collection and let's see what we're going to have in here so we're going to have a text some timestamp and a sender all right so let me just copy this email real quick and so text will be hello there and then we'll have a timestamp that is a type of timestamp we'll just leave it as today and we'll also add a new field called sender let's have the value be our email let's hit save and we should see that appear there all right i'm also going to create another document and have the text be an older message and let the timestamp be from yesterday so fifth let's add the final fill of sender and this time instead of us being a sender we'll have the opposite user be the sender which is test at gmail.com hit save so now that we have our documents here we have to find a way to fetch these data from firestore with our code so i'm going to go and use a hook for this let's copy that import line and paste it here instead of copying use collection i'm going to use collection data which is a different hook here use collection data and i will copy this line and paste it in our chat components down here i'll get rid of the type script and make it all in one line actually don't need loading error snapshot so i'll just get rid of all of that and i can rename values to messages let me get rid of this console log we don't actually need the options here so i'll get rid of that and the query i'm just going to rename that to queue and we can do a const queue equals to the query and i can just straight away query for a collection reference and give it a database handle give it chats which is the name of the collection id of the document and then the messages sub collection so this id is coming from our router's query and i can just leave it like that but instead i'm just going to take an extra step and add a query here from firebase let's cut that and bring it all the way here because the reason for me doing this is so that i can use order by and order by time step so that i'm getting the messages in an ascending order now this collection reference may look strange to some of you because we're actually referencing a sub collection here and if you don't like using the common notation you can always use the slash notation which is the standard that you would use in an operating system and you can change the string into a formatted string to to format the id and this is a totally valid way of referring to the collection i do have other videos on my channel that talk specifically about sub collections and stuff like query and order by so you can check those out if you want to so now that we have access to the messages we can go ahead and console log to see what it looks like in the browser let's go and refresh this you're going to get db is not defined which is fine because i referenced the db handle here in the collection reference but i forgot to import that so import db from firebase config and let's come and look at this again refresh and we're going to get the messages in our console which is an array of two objects so the first object has a text of an older message and the second object has a text of hello there all right so now i'm going to replace all of these dummy messages with our actual firestore data so let me delete all of these and i'm going to move it into its own function called get messages which will return all of the messages components so const get messages equals to um messages dot map and i need to include the question mark here because sometimes firebase takes a bit of time to load the messages and then we do message and let's return this and we're going to get this red underline because we need a key prop i'm going to use math dot random so again don't do this in actual production environments so math dot random i'm going to replace this dummy message with our actual message which is msg dot text and let's save and refresh so this looks pretty nice we have both of our messages here but the issue is that this message is a received message and this is a sent message the received message has to be on the right hand side so i can differentiate the two messages by creating a new const called sender and sender be equal to if message dot sender is equal to our current user so current user dot email and i don't think we have access to our current user yet because we have to import that use auth hook we can import that from app.js so i'm going to import use auth state and let's just paste it here and we can also import um this this line and we're going to put that in our chat component we don't need loading an error we just need the user object to get the current user's email and it requires an auth argument so we have to import auth as well from our firebase config and let's see how it looks like so with the flex here i'm going to just add a property called align self again this is coming from flex flexbox so we'll use a ternary operator that says if sender is true then align self will be flex start or else actually this should be a question mark not a colon and the colon will be here or else it would be flex end and then in the background here instead of just having it to be blue all the time i'm going to use another ternary operator here as well to say if sender is true it will be blue or else it would be green with the weight of 100 let's save and see that looks much better another thing is that when i change between the chats from the sidebar you can see that the top bar doesn't change and that's because user at gmail.com is a hard coded value and instead of using hard coded value we can use the users from the user array inside of our chat document and we can use our utility function that we coded in the previous chapter to get the other email of the other user which is in the chat so i'm going to import um use document data because this time you're fetching data from a document the document of the chat instead of the collection and i'm going to come down here and do const chat equals to use document data and the first argument is going to be the document reference which means i'll use doc db and then chats which is the collection name and the id of the document which we're getting from the router and after that we can go ahead and console.log the chat for now to see what it's giving us so let me refresh this and you can see that right now our chat is returning an array of users which is test as well as Einstein so that's all well and then i'm going to go ahead in our top bar here instead of using gmail.com i'm going to just do email and email is something i can get from the props here so email and down here at the top bar right right here so email will be equal to get other email and we have to get other email let's see what's the first argument which is users which is an array and the current user so users will be chat.users is that right let me see uh yeah that's right chat i'm going to get rid of this console.log and then i'm also going to give this user.email which is our current user actually it's just user because it's going to get the email in this function that's right okay so i'm going to go back to browser get other emails not defined because we have to import that so import get other email let's refresh this and it should give us the email test at gmail.com let's go to hello and this is hello which is all well and as well as plank congratulations for making it the final part final element that we're going to work with and that is this bar down here so technically you should type something here and hit enter and you will send a message that just realize the other complete is still on and i'm going to check to make sure that yeah the other complete is in the wrong place it's not supposed to be in the button but instead at the input so let me fix that and let's see all right so that's fixed all right so let's go look at a code for this bottom bar it's right here and if you notice the input is not controlled input at the moment and that means we're not storing the state of the input in the react state so to fix that i'm just going to import use state from react and let's go ahead and do const input and set input equals to use state nothing fancy here and then we're just going to do on change equals to an arrow function and then we're going to do set input e.target.value and then we have to put e here all right and then we should be able to just like console.log input just to make sure it's working let's do a hi hello all right that's working okay so i can delete console.log and go to the button here and on click equals to send message i can actually do like e and then send message of e and go here and create this function called send message equals an arrow function takes an e and we actually since this is what we're doing we don't even need to write this e is this arrow function we can just straight away put send message here and we're going to do e.prevent default and the reason we're doing this is because we want to prevent the default behavior of the form to refresh the page every time you hit submit we don't want that we just want the button to click and run this send message function and in this function i'm going to await add doc because add doc is an api call to firestore and since you're using await we have to write async here so async and add doc is going to take in it's going to take in a collection reference as like which collection you're going to add this document to and the collection takes in a database handle takes in the name of the collection and it takes in the id and messages actually this is just like a sub collection so we can just do a string format here so chats slash id which is the id of the current chat document and then slash messages and then in this after this we're going to add in like an object here which is the data object and the text there will be the input value the sender will be the user dot email timestamp will just be server timestamp now server timestamp is a way we can add timestamp to our our data object here and you can read that from our firestore documentation here server timestamp it's actually a data type that you can push to firestore to store a timestamp value from the server and then finally after all of these i'm going to just do set input of empty string because the moment you hit enter we want to clear that input so let's save that and see if everything works i'm going to refresh the page and see if everything works so let's type test and hit enter and nothing happens so let's go to the code and check what went wrong here and oh i see it we are using on click here for the button and this is something that we shouldn't do because we are not actually clicking any buttons instead we should do like on submit in the form control here and let's write send message and for this on submit to work in the chakra ui form control we have to use the s prop so we're going to render the form control as an actual hkml form itself let's hit save and then we refresh this and let's type um test message and hit enter and we get this error so i think i know what's going on here it says that id is not defined and if we go to the code and look at our bottom bar we can see that we're trying to access the id here inside of the bottom bar component whereas the id is actually just stored in this chat component which is totally separate from this bottom bar component so we can pass that as a prop here id and then um here then we should have access to the id here then what i'm going to do is go to the bottom bar component and pass the prop of id equals to id let's see if it works now i'm gonna refresh this and it should work so let me type test hit enter it says user is not defined all right so let's go and fix this issue too so user is not defined it's just right here user dot email we're trying to send the user's email as the sender so let's just do user and then you can do user equals to user because the user again is handled by this chat component now refresh again and test yes it finally works so that works but it isn't clearing our input and maybe we have to check what's going on there so here i have to set input to an empty string so that it clears the input after we hit enter and then let's refresh this one last time hopefully it works now and test does it work now hit enter and it still doesn't set the input to empty string so let's see what's going on here hmm all right i think i know what's going on here so in this input here i forgot to set the value equals to input all right that's that's a rookie mistake right let's see if it works now does it clear the input now hit enter and it does it clears the input all right so a cut just happened and all i did was i took the sidebar and the bottom bar component out of this id.js file and i moved them to their own files in top bar of jess as well as bottom bar of jess in the components folder all right let's go back to firefox one last time so here i've populated this chat with a bit more messages now so that it overflows the scroll and i'm going to show you that if i send a new message and i hit enter it's going to send but it's going to be underneath it's not going to be visible until i scroll it then it appears so i'm going to do a quick javascript trick to automatically scroll this chat every time we send a new message so to do that we can create an invisible div at the bottom here at the bottom of the chat messages and then we can use scroll into view in order to scroll to that invisible div at the bottom so here right after all of my get messages i'm just going to create an empty div which is going to be invisible give it a ref of bottom of chat then let's go use um use ref from react which we have to import so import use ref from react because we are using the reference here to reference this div element and then here i'm going to just const bottom of chat equals to use ref and then i'm going to come here and paste a code snippet which is a use effect code and this use effect will basically run every time the messages the messages variable or the constant here gets updated so let's save that and refresh our page and i think we have to import use effect as well so use effect let's refresh this so now it scrolls you see it even scrolls to the bottom the moment we load this page i can hit send new message and it will scroll up the moment i enter so we are at the end of this long course and i want to conclude this course with the final demo to show you how this entire thing works so i'm going to sign in with google here on my right hand side which is a different account by the way so i'm going to type a message here in the left left pane and then the right pane it should show up in real time so demo message it enter and you can see it appears in both windows i can say reply message and it appears in both windows as well and that's it for my full stack react next js chakra ui firebase chat app course all of the code is going to be in the link in the description as well as a demo link that you can go and try out the chat app itself and also if you have any questions please leave them in the comment section i do read every single comment that i get in my youtube channel and check out my other videos especially those on firebase and react