React Chat App Full Tutorial 2024 | Realtime Chat Application Project with Firebase

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Hello friends today we are going to create a full stack chat application using react and Firebase to see this chat page we have to be logged in first if I log out it will show the login component we can create a new account or login and now I can see all my Chats on the left side I can search for an existing chat or add a new user when I select any item here it's going to patch all the chat details and the messages and this chat is real time when I send any message the other user will get that immediately and also when we receive a new message we'll see that on the chat list its background is different because we didn't read that but when I open it it will update the chat and change the background I can also send any image if I block this user I won't be able to send a new message anymore and that user cannot send a message or see our username and profile picture it's a great project to understand react and Firebase Basics you'll learn Firebase authentication to create users Firebase storage to upload images and fire store database to fetch and send real time data and after creating our application we'll deploy it using hostinger as you know it's the hosting sponsor of the channel and I create different projects using hostinger every month and for this project I'm going to choose a VPS hosting if you choose the most popular VPS you'll get really generous RAM and storage that means you can deploy all your full stack projects on a single server and these servers are super super fast because they use mvme ssds and one of the most powerful processors if you want to get a discount you can use the link in the description choose your time period and apply the lamad dev coupon code here after purchasing you are ready to set up your server you can choose in a location and here you can select any operating system and the control panel there are many free and paid options and you can install any of them with just one click I prefer using Cloud panel because it's free and really easy to use we can set a password for the panel and for the VPS and now we can finish the setup it's going to take a while right after that it will be ready to deploy our applications so if you are ready let's create our app and deploy it to this server okay if you created a new folder you are ready to install your react application to do that we are going to be using my GitHub repository you can find the link in the description below and as you can see we have a ster Branch here this Branch includes everything we need to start our react application in the public folder as you can see we have all the images we have es link configuration and and inside the source folder we have an appjs and inside as you can see we don't have anything so we are going to build everything from scratch and at the end of the video I'm going to add here one more folder and it's going to be the completed version of the project but for the beginning we are going to need this Branch by the way it's going to be an open- source project you can use it anywhere you want so I would appreciate if you could give a star for this project and after that that let's download this Branch to do that you can come here and copy this URL and clone this project to your vs code but also you might want to Fork this project so if you create your own repository it will be easier to keep track of your progress so I'm going to click here as you can see this is my test account I will fork and if you do that it's going to create a new report on your account and right now you can clone this project just copy this URL I can use my main account I will come here and copy and on my terminal I will say git clone I'll paste my URL and I want to clone everything in this folder so I will say dot and enter as you can see our files are here but we don't have our libraries let's install I will say mpm install and they are here so right now we can start our application to do that I will say mpm run and Dev let's open up our app and our text is here before starting let me show you the main structure of our application firstly we are going to design our react application and after that we will need a backand to save our users chats and images to do that we are going to be using Google Firebase but there are tons of different Firebase Services which ones we are going to use we are going to use Firebase Authentication we are going to use fire store database and we are going to use Firebase storage when we want to create a new user or sign in we are going to be using Firebase authentication let's say login and register after creating the user we should store the user information and the chat information so we can see our chats we can send a new message so we are going to need this database let's say store user details chats and messages and also we will be able to upload our images so we will upload these files using Firebase storage up load Avatar and chat image and after uploading it's going to return us the image URL and we can store them in our database so inside user details we are going to be using the user Avatar and inside the chat collection we are going to be using the image URL and here when we create a new user it's going to return us a user ID and using this user ID we can store our user details like username user image user chats and other details so all these services will be connected what about our database let me add here our database structure parly we will have the users's collection and each user will have the unique ID username email outar URL and the blocked array we will store here the ID of blocked users and we will have the chats collection each chat will have the created adate and the messages array you might think creating a messages collection and giving chat IDs for each message instead of creating this array but remember fir store doesn't use a relational database searching all messages by using the chat ID might be expensive of course for our application the free tier of Firebase is more than enough but if you have larger applications you should design your database according to your needs and we are going to create one more collection and it's going to be user chats when we visit our application we will get all the user chats on the left side bar so we can patch all these chats using this ID so it's going to be exactly the same ID that our user has so I'll say users ID will be user chats. ID and inside user chats we will have multiple chats let me make this bigger and let me show you what we are going to have in inside this chat object we are going to have the chat ID receiver ID the last message updated ad and is SE Fields when someone sends us a message it's going to be false when we open our chat it's going to be true and what about this message object inside a single message we are going to have the send ID text we will be able to send any image and we are going to have the created ad dat so this is the main structure of our backend right now we are ready to design our application firstly I'm going to give a background for my entire application to do that I'm going to open up the source folder and find index CSS and for the body I'm going to give a background image and I'm going to find my image here let's see as you can see our background is here we are going to use it just like that you can use any image you want and after that I'm going to Center everything in this body because in our application we are going to create here a container and it's going to be on the middle of the body to do that we can use flexbox align item center it's going to Center vertically and justy content Center and it's going to Center our item horizontally okay we can't see our item let's give a class name I'm going to find my appj and its class name will be container I'm going to give some space so it's not going to be 100% 100 VW and height will be 90 VH let's give a background and we can see better okay as you can see it's not centered vertically but because the size of our body is not 100 VH you might ask why this background is 100% if the body is not if you don't know the answer you can visit my second CSS video in that video I explained everything you need to know about this selector HTML element and body element you can find it on the card and after come back here and continue so let's say 100 VH and perfect I'm going to change my text color and let's give here some border radius just like that and right now I'm going to change my background color but I'm not just going to use a background color we are going to also use a backdrop filter and we are going to give a glass effect let's see how to do that firstly I'm going to change this background color it's going to be a blue color just like that as you can see it's a dark blue and I just redu used its oppacity a little bit let's see just like that and also I'm going to give a backdrop filter I'm going to give some blur effect and saturate effect let's see right now and it looks much better but can we use it for every browser let's check I'm going to visit caniuse.com and let's search for backdrop filter and as you can see most of the modern browsers are supporting so we can use it without any problem and let's give a border here I'm going to use white color and again I'm going to reduce its opacity as you can see it's the white color but the opacity is 12 per okay right now I'm going to separate my container into two pieces we are going to have the left bar that we can search for users and our chats on the middle we are going to have our chat component that we can receive messages and send a message and on the right side we are going to have the detail component so we can see the user detail and the chat detail so let's do that I'm going to come here let's close here and we are going to have three components let's create them components the first one will be list chat and detail let's create our jsx files and CSS files just like that let's create our functions and use them inside our appjs I'm going to be using my shortcut if you don't know how I am doing this you can visit my GitHub repos again just find this repository and visit this Json file and inside you are going to see my shortcut cipit and you can copy them and paste inside your cipit just find here your extension in our case is going to be JavaScript react. Json and you can P here your cipit okay so I'm going to save and create the others and also I'm going to add here my CSS files in this project we are using a plain CSS if you want to you can use any UI library or framework but in our application we have have just one page so there will be nothing complex and also we are going to use nasted CSS so we don't have to create a class name for each element when we start you are going to understand better let me write here list CSS and chat so I'm going to come here and write my components first one will be list chat and detail let's import them quickly just like that so let's see on the browser okay our items are here but I want to make them horizontal so we can do this easily using flx boox I'm going to find my container and I will just say display Flex they are horizontal let's give a size using flexbox for the chat component I'll say flax 2 let's give our class Name by the way and for detail is going to be flx one I can do this same thing for the list flag one so they are going to be smaller just like that as you can see chat is much bigger and this is what we want and let's create our elements for the list component firstly we are going to have here our user information we will show our image and username and some icons to do that I will create here a new component and let's say user info jsx let's import our CSS and after that information we are going to have our chat list so I'm going to create one more component just like that so let's use them inside our list the first one will be user info and the second one will be chat list just like that so let's create our user information on the left side and for the right side we are going to add some icons I'm going to come here and let's say user and one more and it's going to be icons the first one will be more. PNG two more video and edit.png and for the user container we are going to have our user image of course we don't have any data yet so we can use our Avatar PNG for now and after I'm going to create h2 tag and it's going to be our user name let's say joho for now okay let's give a style firstly I'm going to give here a padding and I'm going to make my items horizontal let's say 20 pixels display flags and I'm going to Center them vertically and separate my items using justy content okay this image is too big let's give a style and also I'm going to move this username here so they are going to be horizontal again so let's use our user container display Flex align item Center and gap between our image and username will be 20 pixels let's give a style for the image 50 pixels it's going to be a circle so I will say 50% border radius and object fit will be cover okay perfect what about those icons again I'm going to give a gap between them and reduce their sizes after this user I will say icons gap between them 20 pixels and I'm going to choose my icons and they are going to be 20 just like that and we can click on them perfect and what about our chat list firstly I'm going to create here a search component and on the left side we are going to have our search bar on the right side we are going to have add new user button and after that we can show here each individual chat and they are going to have a user Avatar a username and the latest message I'm going to close everything here open up my chat list and inside let's create our first container and it's going to be search let's say search bar and inside this bar we are going to have our image search image and the search input I can give some placeholder and I will say search and finally after this search bar we are going to have a button and we are going to be using plus. PNG so when we click on this button we will be able to add new user let's give a style I'm going to make them horizontal as we always do I'm going to open up my CSS here for the search container let's say align item Center gap between items will be 20 and padding will be 20 but I want to make this search bar a little bit bigger our button will be at the end of the container and the rest of the container will be our search bar to do that we can use flex again search bar and I'll say Flex one just like that let's give a background color again I'm going to be using my dark blue color let's give it semicolon here and I will paste my color here as you can see the opacity is 50% okay perfect let's Center our items and I'm going to give border radius okay let's get rid of this inut background and this border input and the background color will be transparent I'm going to delete the Border outline and the text color will be white perfect but as you can see if I click here it's not choosing my input because it ends somewhere here again I can use flx just like that perfect let's reduce this image size it's going to be 20 pixels after this input I can give here some pading and it's much better right now so what about this image let's give a class name here and I will say at and I'm going to make this a little bit smaller I'm going to give exactly the same background color let's copy and paste let's give some padding and Border radius and we can click this so I'm going to give cursor pointer okay but where is our padding oh I said zero is going to be 10 pixels okay it's much better right now and when I click on this button I'm going to change my icon and it's going to be minus PNG to do that I can create here a use State I'll say add mode set add mode I'll say use State hook and the beginning it's going to be false but as soon as I click on this button it's going to be true and using that state we can update our icon I'm going to copy this and write my condition here I will say if it's add mode use minus PNG if not plus PNG and whenever I click on this button I'm going to I'm going to change my state on click set add mode I'm going to take the previous state and right here the opposite so when it's false when I click here it's going to be true let's see I'm going to click as you can see minus PNG and plus so right now I can add my chats let's close here here and after this search I can start adding my chat items let's say item and inside we are going to have the user image for now again we are going to be using aatar PNG after patching data from the database is going to be dynamic and after that we are going to have the TX container and it's going to include our username let's say chain door and the latest message of that chat let's say hello for now okay again they are going to be horizontal but before let me add some more items so we can see the space between those items as you can see it's overflowing what I want to do is I want to give a scroll effect for this container so if it overflows we are not going to see them here instead we will be able to scroll let's open up our CSS again after this search I'll say item let's Center this give gap between items and I will give padding and we can click on our items and for each item I can give border button so we can separate them border button one pixel solid and this gray color just like that so I'm going to get back to my container and give my scroll effect so I will say flag one again so it's going to contain all our container and overflow will be scroll okay it's still overflowing because we used Flex here but our parent is not a flex box and I will say display flex but it's not going to be horizontal I'm going to be using Flex Direction and column and right now I can scroll down Okay so let's reduce this image size and separate our text I'm going to close here in inside item I'm going to find my image and it's going to be 50 pixels it's going to be a circle and object fit will be cover and after this image we have the text container again I'm going to be using Flex box but they are going to be vertical and gap between our texts will be 10 pixels and for the username font weight will be a little bit thicker and for the last message it's going to be smaller and the font weight will be 300 just like that so let's give a border for this chat component we are going to have a border here on the left and on the right and we are going to be using exactly the same color let's remember this one so I'm going to open up my chat component and I will say border left border right and perfect so let's take care of our chat component firstly we are going to have the user information here and this container will include the user image username and again on the right side we are going to have some icons and after this user information we will be able to see our chat messages and on the bottom we are going to create an input that we can send our messages so basically we are going to have three main sections top Center and bottom let's do that I can close them open up my chat component and I'm going to create my containers top Center and bottom we are going to have the user information and icons and inside user information again the user image and let's say texts chain door and a P tag and it's going to be the user description let's write here something random just like that and inside icons we are going to have three icons first one will be font. PNG video and info I'm going to separate my items give some padding here let's do that I'm going to open up chat CSS and let's move it here make this a little bit bigger and again I'm going to say height 100 % so it will be easier to separate our items for the top I'm going to give some padding make this horizontal the line item Center and justy content will be space between and again let's give this border border button just like that what about this user we are going to do exactly the same thing if if you are using Flex boox everything is much easier 20 many pixels and for the image let's make this a little bit bigger 60 pixels again a circle and object fit we are using object fit because if you don't do that it's not going to crop your images is going to try to fit inside this container and it will look a little bit weird if you want want your images to be sharp you have to use object fit it can be cover or contain and after this image texts let's say Flex Direction column and the gap between username and this description will be 5 pixels let's increase this font size and font weight 18 pixels uh font we we will be bolt and for the P tag it's going to be smaller one we will be thinner and I'm going to give a color and it's going to be a soft gray just like that so let's separate our items here icons user ends here so I will say icons cap between items will be 20 and for each icon inside size will be 20 okay before creating the center component let's take care of the bottom it's going to be much easier we are going to have icons on the left side on the middle we are going to have our text input right next to that input we are going to have the emoji icon and finally asend button I can close here for now and let's say icons text input let's say placeholder type a message after I'm going to create my emoji container inside that we are going to have our icon and after giving our style we are going to add here one more component and it's going to show our emojis to do that we are going to need a library but for now let's give our style so I'm going to create my button send and let's give class name sand button okay I forgot my icons again we are going to have three icons image. PNG camera and Mark profile okay let's separate them I'm going to open up my CSS file after this top I can create Center and bottom and inside this I'm going to give some padding and make this horizontal and again I'm going to give my background sorry border and it's going to be border top okay we cannot see it right now but when we move our items here it's going to be visible before that let's give size for our icons G 20 and for each image is going to be 20 just like that and what about this input after icons I'm going to choose my input Flex one and again I'm going to delete the background color transparent border none outline none and the text color will be white of course it's not the class name just like that actually I can give exactly the same background here instead of transparent I'm going to come here and change my background color just like that and as you can see it contains all our container but there is no space here let's give I will find the parents and I will say Gap to any okay I will give some pading key here it's too small I can give border radius and phone size will be 16 pixels just like that and for this button again I will make this a little bit bigger change background remove the Border what was the class name sand button first the background color will be the this blue color and the text color will be white I'm going to give some padding for top and bottom and for left and right let's delete the Border 5 pixels radius and we can click just like that I want to decrease this icon also it can be exactly the same size so what we can do is move it here so it's going to be all the images inside our container just like that so what I'm going to do is install my emoji picker so let's install I'm going to open up my terminal create a new one and I will say mpm install Emoji picker react okay right now we can use our picker component I'm going to close here for now and I will say import Emoji picker from emoji picker react let's use this component after this image I'll say my component and as you can see it's here but at the beginning it shouldn't be here only when I click on my icon it should be visible to do that we are going to need a use State hook const open set open use State let's say false and using this variable we can write our condition to do that we are going to be using the open method and I will say open if it's true right now it's not here so when I click on this button I can update my state so let's say on click set open take the previous state and right here the opposite I will click and it's here of course we are going to change its position but for now it can stay like that and when I click on any Emoji here nothing is happening what I want to do is add this Emoji to my input to do that we are going to be using on emoji click event let's say handle Emoji let's create our function here and let's see what's inside this event I'm going to open my console let's choose any emoji and as you can see it Returns the name of the Emoji image URL but we are going to need the is Emoji so using this value I can update my input here but before let's create another state that we can update our input so I'm going to create one more and it's going to be text and at the beginning it's going to be an empty string and whenever we write anything in our input we are going to update our state to do that we can use on change event set text and Target and value let's see I'm going to write something and as you can see it updates my state so when I click on any Emoji here again I'm going to update my state and at the end of the text we are going to add this emoji I will come here and say set text take the previous value and write it again but also add this emoji and after that we can close our emoi container we don't need this anymore just like that let's use this text here as a value and let's see I'm going to refresh hi I'm going to choose emoji and it's here perfect let's change its position I want to see this component on the top right I'm going to open my CSS let's see again we have Emoji image and this p let's actually create here a container and I'm going to change its position after this input we have the Emoji container and its Position will be relative because for the pier we are going to be using absolute and I'm going to give my position here let's say 50 pixels from the bottom and the left will be zero oops there's a typo here and let's see I'm going to refresh when I click as you can see it's on the top right of course it's overflowing but it's not important because our component will be here on the bottom to do that I'm going to give Flex one for the center and after I'm going to move my item to at the end of the container to do that let's open up Center again I'm going to give padding and flex will be one and if I say margin Top Auto it's going to move my item but as you can see Flex doesn't work because our parent is not a flex box display flx Flex Direction just like that right now when I click as you can see our picker is here okay awesome so what about Center let me close here and for each message we are going to create a du and that du will include the user image user text and the date of that message and if we send any message to that user we are going to see it on the right side but this time we are not going to have any image and again if it overflow we will be able to scroll just like here let's do that I'm going to come here close this chat and inside Center I'm going to create my first message let's say message D and it's going to include the image avatar.png and after we are going to have our text the first one will be our message let's create here a random text and after we are going to have our span that shows the date of that message I will say 1 minute ago so let's create other messages and if we are the owner of that message we are not going to have any image and the class name will be message and all again the other users message our message other users message and our message okay let's give here overflow I will say scroll I will give display flags flags direction will be column and gap between each message will be 20 let's create our message and I will say maximum width 70% and for image and text container we are going to give a gap so we can use flex boox and just like that as you can see it's not 100% when we add our own message here on the right side it's going to look much better let's do that that I will say if it's message and also on align s will be flex and just like that and I can change this text color actually inside own I will choose texts and the P tag inside and the background color will be this blue color just like that we are going to give some padding Insight but before let's take care of the old text container because we have an image here I will say image and texts and for the image I'm going to give width and height as we always do 50% and object fit and for the text I will give Flags one and it's going to be vertical and gap between items five pixels okay right now we can give padding for our items our P tags let's give 20 I'm going to give background color if it's not our message it's going to be this dark blue color just like that and its oppos will be just 30% and I will give border radius 10 pixels and perfect what about this date it's going to be smaller just like that what if a user sends an image we are going to show it about this text let's add for this one the latest one before this ptag I'm going to add an image let me copy and paste quickly and as you can see its size is small and it's a circle because we used image here but for the image inside text container I I will say 100% height will be 300 let's give some border radius and again object withit will be cover just like that okay perfect and what about detail again we are going to create the user information the detail of this receiver and after that we are going to add here some options that we we can see the files of this chat or photos of this chat and finally we can add here a button that we can block these user let's do that I can close them and open up detail and again a user container and let's say info container and inside this user we are going to have the user image username chain and the user description again I'm going to generate a text here it's going to be shorter and after this user we can add here our options each option has a title so we can show the title Texs on the left and the icon on the right first see I will say option a title div let's say chat settings and image and it's going to be Arrow up.png let's create some more privacy and help shared photos is going to be arrow down because we are going to show our images here so after this title let's say photos and inside this container we are going to have our image the image name and on the right side again we are going to have an icon so let's say photo item and each item has an image let me copy and paste this image and the photo name let's say any random text here and on the right side we are going to have our icon and it's going to be download.png okay we are going to give style for our images but before let's add our last title and it's going to be shared files and after this option we can create here a button that we can block the user okay let's open up our CSS actually I can add here more items by the way it should be like that and to separate this icon and these items I can create here one more div and it's going to be photo detail okay because we are going to be using justy content space between and I want to separate those items and this icon okay let me create some more items here okay and let's take care of user div here firstly let's give a pedding display will be Flex let's give semicolon here and after that Flex Direction column I'm going to Center my items and gap between each item will be 20 pixels and after I'm going to give my border remember one pixel solid and this gray color just like that of course this image is too big let's choose our image and I will say 100 pixels object withd and Border radius okay and for this info container again I can give padding and separate my items after this user remember we have the info container here I'm going to give some pading it's going to be vertical and gap between items will be 30 pixels and for each option we have titles I'm going to separate them just like that let's decrease this image size and give cursor pointer it's going to be totally pixels I'm going to give my dark background color just like that let's give some padding B the radius and cursor pointer just like that and what about our photos let's decrease this size inside my option we have horos Flex direction will be column and gap between our items will be 20 and inside we have photo item and inside this we have foro detail and finally let's fix this we are going to have our images and they are going to be 40 pixels I'm going to give some border radius let's say five and object back fit okay right now it looks much better and let's separate our items here our logo should be here I'm going to come here and say display flx line item Center justy content space between just like that and I can do the same thing for this information I'm going to separate them and Center vertically align item Center and GAP okay I can decrease this size and change the color after this image we have a span it's going to be smaller gray actually let's say light gray and font weight will be 300 okay actually we can show here maximum four images I'm going to delete this photo item and the second one okay and let's give class name for those icons so we can give exactly the same style I'm going to find download PNG and I'm going to give class name for them and I will say icon and inside this photo item I I can choose my icon it's going to be 30 pixels again background color padding it's going to be a circle and csor pointer just like that by the way I can give here a space so I'm going to find my parent de and margin top will be 20 okay perfect by the way there is a typo here it's going to be end and finally we have a button here it's here so inside information we have our button I'm going to give some padding from top and bottom left and right it it's a danger button so its color will be this red color the color will be white I'm going to delete the border and give border radius and cursor will be pointer okay it's not here our information is here oh I said inside option it should be outside okay it's not here okay it's here and when I hover over I can change its color it can be darker I'm going to come here and say if how make it this color as you can see I just increased its opacity just like that what else we can do if I refresh my page as you can see the first items are here but whenever I open my chat I want to scroll down to do that we can use us ra hook I'm going to close them open up my chat component and after all these messages I'm going to create a div here and I'm going to write anra remember it's under all our messages so I can use usif fact hook and whenever I open my page I can scroll to that div to do that we can use use ra hook const and dra use RAF hook and whenever we visit our page we are going to run this effect it's going to run once and we are going to be using our ra here and I will say scroll into view and we can change its speed here using Behavior just like that let's see I'm going to refresh as you can see this is what we want what else we can add maybe we can add here a log out button I'm going to close here open up detail and after this button I'm going to add one more and I'm going to give a class name let's say log out let's open up the CSS file and I will say if the class name is log out padding will be 10 pixels and the background color will be this blue color let's increase the padding of this red one I will say 15 pixels okay and the space between each item is too large maybe let's make this 25 and I also want to reduce this container withd it's too long let's check index and as you can see it was 90 I'm going to make this 80 okay and finally maybe I can reduce this user size or space between them I'm going to come here let's say 15 and it's much better right now of course if I make any changes you can find it in the GitHub repository but for now it's enough I don't want to waste time let's take care of our login page I'm going to close them and open up my appjs and my menu and here let's create one more component and it's going to be login CSS and JavaScript file let's create our function firstly I'm going to write here a condition of course we don't have any user yet but I will say if we have a user we are going to show our container and if you don't have any user let's say false we are going to show our login page let's do that I'll say if there is a user call the component if not call the login page just like that of course we should have a parent here just like that I'm going to import login we are on the login page so what I'm going to do is I'm going to split this login page into two pieces the first one will be our login inputs and the second one will be the register inputs so when we want to create a new user we are going to use the right side if you want to log in we are going to be using the left side so I can close here open my page and let's say item and the second item and between them we can create a line let's say separator and in the first item I'll write a title and let's say welcome and after that our login form the first input will be email input name will be email and the second one will be password just like that and after that let's create a button and I will say sign in let's do the same thing for the second item this time I'll say create an account again email password but one more and it's going to be username just like that and remember when we register we can upload an image so let's create that I'm going to create one more input and it's going to be a file and I'm going to give an ID let's say file and it's here when I click here I can choose any image but I don't want to see this input instead I'm going to create a label and I will say up upload an image and it's going to look better let me show you and you are going to understand better if I say label and the ID of my input which is file when I click on this label it's going to automatically run this file input let's say upload an image when I click on this text as you can see it opens my folders right now we don't need this input anymore we can hide it let's use inner style and I will say display n okay we have only this text and before this text we can show our image and right now I can write my condition if user selects any image we are going to show it here if not we can show the Avatar PNG of course to do that we are going to need a state let's come here const Avatar set Avatar use State hook and I'm going to create here an object the file will be null and the image URL will be empty string so basically at the beginning we don't have any file but if user selects any image here let's say on change I'm going to say handle Avatar let's create this and we are going to set our state set otter and the file will be you target files and the first file we can upload only one image which and I'm going to write here URL and I'm going to create an object URL because when we select an image I want to show it here immediately to do that we are going to need the object URL so I will say URL create object URL and I'm going to pass here my file again just like that of course if we click here and don't select any image it's going to run this handle Avatar to prevent this we can write here an if block and I will say if there is an image okay right now I can show this URL I'll say if there's an avatar show the URL if not show the Avatar PNG just like that if I select any image here as you can see it changes our Avatar and I'm going to update Here sign up and that's all let's take care of our style firstly let's say size 100% I'm going to Center my items and gap between left and right side will be 100 pixels and for the items I will give flx one so their sizes will be equal and display flx flx Direction column align items Center and gap between titles these titles and form will be 20 pixels and when it comes to forms again I'm going to separate my items justy content Center and gap between items will be 20 just like that let's give a padding for our inputs padding 20 I'm going to delete the border and the outline my background color will be this dark color text color will be be white let's give border radius 5 pixels just like that let's take care of this label inside our form let's say label is going to be 100% let's separate our items justy content space between and I'm going to give cursor pointer and underline here and when we reduce this size it's going to be a space between them that's a cursor pointer and the text decoration will be underline and I'm going to select my image it's going to be smaller I'm going to give some border radius and of course object fit okay maybe I can decrease its opacity because we are using this glass effect so let's say opacity 60% okay so when I click here I can choose any image and it's going to be on our component just like that what about buttons after this label again 100% I'm going to give my padding delete the border the background color will be this blue color text color will be white and Border radius of course we can click just like that let's increase font weight what about our line here let's give a height and width it's here after this item let's say 80% and width will be two pixels and the background color will be our gray background color just like that and one more thing if we have any error or success message I want want to show it somewhere here to do that we can use a library let's open up our terminal and I will say mpm install react toastify to do that I can create a new component let say notification let's close here and I'm going to show my library component here and it's going to be TOS container and I can give here any position and I want to see this on the bottom right of course we need to use it CSS file just like that and right now I can use my component on my appjs let's write it here I'm going to import and let's try actually we don't need this CSS I can delete we already have this CSS file and I want to test it let's say on submit handle login if you are using a form when you click on this button it's going to refresh the page to prevent this we are going to be using event prent default and after that I want to call my notification to do that we are going to be using our library and you can give here the type of the notification let's say Warn and our message here let's try I will click and as you can see it's here if you say success the notification will be green this is how it works if you say error it's going to be red okay perfect so if we have any error or success message we can use this Library let's remove this for now and that's all I think let's open up our containers everything looks great maybe one more thing here when I click on this button I want to show here a model that we can search for any user of course we can do it on this input but we will also search for the existing chats if we use exactly the same input everything will be more complex to prevent this let's create one more component and show it on the middle of the container I'm going to open up my components and let's say add user CSS and jsx let's give class name and import basically we are going to have here a container at the top of that container we are going to have a search bar and search button when we click on that button it's going to show our users so let's create a form I'm going to close this menu and after this form one more div and it's going to be the user inside this form we are going to have the search input let's say placeholder username and I'm going to give the username name and after a button and I will say search and if we find any user we are going to show it here and this is going to include our username and image and on the right side we are going to have a button that we can add a new user here so that's a detail and a button and here is going to be the user image for now I'm going to say Avatar PNG and the username okay let's use it on our chat list actually I can move this folder inside chat list because it's going to be a sub component and let's use it here I can use it at the end of the component just like that and its Position will be absolute and let's give a style I'm going to give part pixels padding I'll give my dark background color and Border radius let's give our position to see this component on the middle of the screen I can give zero for each Direction and if I say margin order it's going to be on the middle of the screen we don't have any size let's say maximum content and height and as you can see it's here let's take care of this form it's going to be display Flags gap between items will be 20 and for the input I'm going to give some padding and Border radius and I'm going to delete the border and the outline just like that and for this button let's give a padding and our background color again time pixels background color will be this blue color and the text color will be white and we can click cursor pointer okay what about this user again it's going to be horizontal after this form I will say user firstly let's give margin top I want to separate this user and this form and as always display Flags align item Center and just five content space between let's reduce this image size remember we have the detail container and inside we have our Avatar it's going to be 50 pixels border radius and object fit and again I can separate my username and image perfect and let's give exactly the same style here but this time I'm going to reduce my padding it's going to be 10 okay maybe we can increase this dark color just like that and I can write here my condition right now if we click here we are going to see this component if we click back we are going to remove it let's open up our chat list if you remember we have the at mode here I can use this as a condition just like that I'm going to refresh it's not here but when I click it's here okay so that's all we finished our design part if I make any changes you can find it in the GitHub repository so let's take care of the backend part to do that we are going to be using Firebase let's come here close everything and install our library so let's open up our terminal and install Firebase mpm install Firebase after this installation we are going to need the configuration to do that let's visit console. firebase.com and let's create a new project and I will say react chat we don't need this let's create our project it's going to take a while during this process let's create our file I'm going to close these components and create a new file here let's say library and inside fire base.js so we are ready to write our configuration here okay our project is ready we are going to create a web application let's click here let's give a name again react chat and this is how we can write our configuration let's copy this and paste inside our file I'm going to close here if you want to you can add this API key into an EMV file let's do that I will say em and let's say API key and paste this here let's use this but if we do that it's not going to be visible on the client site but for the login process we need our API key on the client to do that I should add here with and right now I can reach my data to use this here we are going to be using import meta EMV and the variable name just like that let's remove those commments just like that I'm going to save and let's see what else we need I'm going to continue and right now we are going to build the Firebase authentication as you can see there are many providers here you can use any social media provider but also you can log in with email and password let's use this I will enable and right now we are ready to create users but to save our user information like Avatar and description and and to save our chat information our messages we are going to need a database to do that we are going to be using Firebase fire store let's click here create a database just choose here any location we can start with the test mode in this case everybody can create data but after creating our application we are going to change here let's create and during this process let's export our storage and Firebase authentication to do that I will say export const off get off okay I can't import let's import manually I will say get off from Firebase off I will do the same thing for fire store get fir store let's export this also I will say database and it's going to be cat fire store and one more thing we are going to need and it's going to be our storage because in this application we want to upload some images to do that we are going to be using Firebase storage let's create again I will say test mode and let's export this get storage from Firebase storage and I'm going to export this here I'm exporting them because we are going to be using them on our Pages for example on the login page we are going to upload our images using this storage and we are going to create our user information using this database and we will be able to login or register using this authentication okay I can close here and our application is ready let's see how to login and register firstly I'm going to open up my login page and if you remember we have a form here to register form let's create here on submit event and I will say handle register let's create our function I will close my menu and come here and we are going to do exactly the same thing and I will say handle register and if you remember inside our our form we have four inputs file username email and password using those names we can reach to our items and for this file we already change our Avatar we can use it directly so what I'm going to do is create here a form data new form data and using this we can read to our username email and password it's going to come from this form data to do that we can use object from entries and pass here our form data let's see of course to see our login page we should update this user it was true that is going to be false I'm going to open up my console write here and think okay it's not here because I didn't pass here my event Target basically it represents our form and inside this form I can reach my inputs using their names let's see again and John is here this is how it works so right now we have our inputs and we can select any image but for the authentication remember we are just going to need the user email and password so basically for the authentication we are just going to need this email and password but after creating our user we can store this username and this Avatar into our database we are going to take care of this later before let me show you how to create a user using email and password firstly I'm going to write here a try catch block if we have any error we are going to show it here and also remember we can show our notifications using our library it's going to be error and error message so let's create our user of course it should be an async function because we are making a database request and I will say const response await and we are going to call create user with email and password method and we are going to pass our inputs let's import this first from Firebase off and remember we have the G up he function we have to use this function inside this method because otherwise it will not know our Firebase configuration let's do that create user with email and password we are going to pass here our off method and after our email and password let's see I'll write here John gmail.com any password here I will sign up and let's check our Firebase I'm going to come here and as you can see it's here and this is its user ID okay this is how we are creating user but as I said we need our user information to do that we are going to be using our database let's see how to add item to Firebase fire store I'm going to open up the documentation let me zoom in add data we already have our configuration and after that as you can see we are going to need the set document method and inside we are going to pass here our database which is in our Firebase Jaz here and after that we are going to write here our collection name in this case it's going to going to be users you can give here any specific ID and remember in the authentication we have the user ID we can use exactly the same ID here and pass our username and aatar I'm going to show you how to upload image later but before let's try to add our user I'm going to copy here let's import them just like that Dock and set do from Firebase fire store and database from our Firebase file as I said the collection name will be users and we are going to pass here the ID that comes from this response and it's going to be response user. ID let's delete this user because we are going to create a new one and we are going to pass here the username is going to be the username that comes from our form and since we are using exactly the same name we don't need to write here we can use it directly like that and also I'm going to pass my email and also let's pass here its ID we are already storing our document with this ID but I'm going to pass this ID into my database also because when we search for our user it will be much easier to use this ID instead of this one when we do it we are going to understand better and also when we create a user we are going to have a blocked list at the beginning it's going to be an empty array when we block any user we are going to pass the ID of that user here and if everything is okay we can send a notification it's going to be a success message and let's say account created you can log in now and I want to create one more document by the way because when we login remember we are going to patch our chats but at the beginning of course it's going to be an empty array let's create one more set document and it's going to be user chats and again I'm going to pass here the user ID and the chats will be an empty array we are not going to have any chat okay when we create a new user it's going to automatically create our user and user chat in the database let's try don't have any user here okay let's create I will say John again our mail address and password I will sign up as you can see our notification is here if we check our fire base we can see that our user is here let's check the database as you can see chats is empty and inside users we have our information and as you realize this ID and this ID are equal but there is one more thing here we have to upload an image so again let's delete those Collections and this one and our user here because this time we are going to need an avatar let's see how to upload an image again inside the documentation as you can see we are going to be using our storage and after that we are going to create a reference we are going to pass our storage and the image name and after using this reference we are going to start uploading our images let me scroll down and show you the completed version of this process as you can see we already have our storage we are going to create a reference using the name and after we are going to be using this method we will pass here our reference and the file remember in our application we have outter and inside we have the file we are going to pass it here and start our uploading process and the best thing is we can control our progress if we cancel uploading we can show any error if something goes wrong we can show again notification and if everything is okay it's going to return us our image URL and we can send to our database this is the idea so let's copy here I'm not going to paste it here because when we send a message again we are going to be using this upload method to not repeat ourself I'm going to create a new file inside Library I'll say upload. JS let's create our function upload it's going to be an Asing function we are going to pass our file here and using this file we are going to start Firebase upload let's export this export default upload okay right now we can use this function everywhere and I'm going to paste my function here let me close this menu and remove those commments so what I'm going to do is turn this function into a promise because I want to return this download URL in our component we can use it in this TR catch block and we can say const image URL await upload and we are going to pass here our file so we are going to await this process in this case it should be a promise so I will say return new promise resolve and reject if there's an error we are going to reject this promise and send that error and I'm going to wrap my upload task just like that and if there is an error we are going to reject let's write here any message something went wrong and we can pass here our error message or error code and here if we have the download URL we are going to send it so I will say resolve and send this URL by the way there is something wrong here let me fix it of course it shouldn't be here let's take this back and remove this okay so right now I can import my functions just like that storage from Firebase Jazz ra from Firebase storage okay we can directly use here file. name but if we use exactly the same name when we upload image it's going to be a conflict to to prevent this we need to pass here a unique name to do that we can use a date new date so it's going to create here a unique Tim stamp let's say images folder and after this date and also the image name okay if you want to you can reject when you pause uploading but actually we don't need here if you want to you can show your progress and that's all I think we can use it on your login page let's do that we can take the image and we can paste here AAR will be this image URL so let's try I'm going to refresh my page let's choose any image here John and password I'm going to sign up okay there is Success message I'm going to refresh my user is here this is the ID let's check our database inside users as you can see we have AAR and all these information and in the chats let's check the ID and this is exactly the same ID okay this is what we want and right now using this login form we can sign in but before I want to add here a loading indicator when we click on that button we are going to show a text to do that I'm going to create here one more use state after react 19 we are going to be using form actions use form State use form status hooks but for now since react 19 is still better let's use the old way so I will say loading set loading use State hook at the beginning is going to be false and when we click on that button it's going to be true and if it's successful or if there's an error we are going to make it false again so I will say finally set loading will be false so let's disable our buttons using this loading I'm going to also disable here if it's loading and I'll do exactly the same think here and let's open up our CSS file and for button I will say if it's disabled cursor will be not allowed and let's change the background color it was this color but I'm going to reduce its opacity just like that okay let's save and I can write here a condition if loading write here loading if not sign up I can do the same thing for the login just like that let's try I'm going to refresh choose an image Jane I'm going to sign up as you can see perfect and our user should be here as you can see we have two documents and inside users chane is here so how we are going to login it's much easier again we are going to be using our inputs and after that we are going to be using sign in with email and password method as you can see it's here let's use it inside login again I'll say async try catch if there's an error console log and also send the notification finally set loading will be false and when we start this function it's going to be true and again I'm going to take my data that's copy here just like that this time we are not going to need this username and after we are going to use it in this function let's copy this 8it and inside again we are going to pass our off function email and password and that's all let's see I will say John and password I will sign in okay this is the username of course it's going to be email and as you can see there is no error that means we are logged in but how we are going to know that we are logged in we have to store our user information somewhere if you are using Firebase it's really easy to keep track of your login process I'm going to close them open up my appjs and I'm going to write here use a fact hook and and using this user fact hook we can listen authentication when we create new accounts when we log in or log out it's going to always listen our authentication and it's going to send us the latest stas let me show you how to do that remember if you are listening any real time data you have to use a cleanup function and sa on of State changed we are going to pass here our off function and it's going to return us our user using this user you can do anything you want let's console loog and after that we are going to create here our clean up function just like that if you didn't watch my user fact video you can watch it to understand this cleanup function that video is a little bit outdated but it's important to understand the user fact Basics after react 19 I'm going to create one more video about use effect okay I'm going to save open my console and as you can see we have the user here its email is here its user ID is here and in this case we can fch our user information from the database using this ID and and we can store it on our application and in that case if we have a user we are not going to see this page anymore we are going to see our chat container and using the user ID we are going to patch our chats so what you can do you can get all the user information from fir store here but I want to show you how you can store your items using react State Management tools because if you use a state management tool you can store your items easily and you can get those items inside any component you want before starting let me show you why react management tools are important in our react app we have the appjs and inside our appjs we have two main container the first one is login container and the second one is the chat container so if we have a user in our appjs we are going to show the login container if we don't have we are going to show the chat container to do that we can use a use State and store our user so if there's a user show the login container if not show the chat container in this this case we need to take this user from the appjs we need to pass this as a prop and also inside the chat container we have different components we have the list component chat component and details component and again we need to use the user on those components because remember inside list component again we have two components and inside chat and detail inside the list component we have the user information component and the chat list component and inside chat we have the chat messages and the text input and inside detail we have the user detail and the chat detail and again we are going to need to use the user information inside those components to do that we should take this user from the parent and pass them here and for the child components again we should pass them and if you remember inside details we have the logout button when we click on that button it should remove our user in this case we have to use this set user function so now we also need the set user and we have to pass it here and here and here and for the login container after the login process we should update our user and that means we are going to need our set function here in our application we have just three components but imagine you have many others and you shouldn't send your States like that this is called prop drilling if you use this method you are going to unnecessarily reender your components and also you will probably forget some States and make some mistakes what if we have an independent state somewhere here and this state will store our user information and the set function and what if we can get this user and set user whenever we want and in any component we want for example in the chat container we can directly say give me the user or in the chat list again I need the user or in the logout button we can say I want to set the user so as you can see we don't have to pass the information through our parents we can directly get this information from this store in this case no more prop drilling no more un necessary rendering everything is much easier so this is the idea of State Management tools so let me show you how to create a store and how to store our states the most popular one is reduxx but I want to show you my favorite one zand it's really easy to use as you can see we are going to need this Library let's install quickly mpm install Z stand and after that we are going to create our store using the create function and as you can see you can create any state here and using some actions you can update your state for example when you call this action it's going to get the previous state and increase that number so whenever you call this action on your components it's going to increase this number and here we have another action and it sets the state and makes it zero again or here you can pass any data on your components and using that data you can update your state so let's create our user store and you are going to understand better I'm going to copy here we don't need this anymore I'm going to open up my menu and inside Library let's say user store I'm going to paste it here and I'm going to change this name it's going to be use user store because later we are going to create one more store and it's going to be use chat store let's close here by the way and inside my state we are going to have the current user let's say null and let's create an action I'm going to delete them and I will say fatch user info it's going to be an Asing function we are going to get the user ID and update our state so basically whenever our authentication status changes we are going to take this user ID remember the ID is inside here we are going to pass this to our action and using that ID we are going to update this user we are going to fatch the Avatar we are going to fatch the username or whatever it might be inside this database let's do that firstly I will say if there is no U ID that means we are logged out in this case and I'm going to return set State the current user will be null and also I can create here one more item and it's going to be is loading because whenever our state changes is loading will be true instead of any blank page or error we are going to show this is loading indicator and I will say at the beginning it's going to be true and whenever we end our patching operation it's going to be false just like here is loading it's going to be false and after that if we have a user ID we can fatch the user information let's say try catch if there's an error it's going to be exactly the same and by the way we can show this error for the developer M mode and inside this Tri block we can get our data let's see how to do that again we are going to create a reference and we are going to write here our collection name the ID of the document in our case is going to be users and the user ID and after that using this function we are going to get our information and if we have that user using this data function we can reach to our Avatar and username let's do that I'm going to copy here and paste let's import this and DB it's going to be users and we are going to pass here our user ID remember it comes from here and after that we are going to get the document if it exist we are going to update our user using this data so let's say Set current user is going to be this data is loading will be false and else if we don't have the user it's going to be null and is loading will be false again and let's export this so using this store we are able to reach our current user and is loading and this hatch user info action so let's use them here I'll say const from use user store and right now I can reach current user is loading and fatch user info so let's use this first I will come here and I will say if it's loading return a du and right here loading let's give a class name and update our D using index CSS because remember our container is here first say I'm going to give a padding font size will be bigger border radi and the background color will be this dark color okay let's save and right now instead of this user we can use current user and whenever our state changes we can fatch our data and we are going to pass here the user U ID in this case our dependency will be this function let's see I'll say console lock current user I'm going to save and as you can see we are not on the login page anymore if I refresh my page as you can see loading and after we are on the homepage if I open up my console you can see that our information is here and we can use this information inside this component this component here or in details wherever we want this is how important to use State Management tools by the way of course it's rendering twice because we are using the streak mode here again if you watch my user fact video you are going to understand the reason but don't worry it's just for the development mod when you deploy your applications it's not going to render twice so let's use this information here I'm going to copy this I will save close everything and open up user info let's import here we are going to need only current user and here is going to be current user username and we can write here our condition use the current user Avatar if it doesn't exist use this Avatar PNG I will save and as you can see our information is here what about this logout button I'm going to open up my detail and it's really easy to log out I will just create here on click event and whenever we click on this button is going to call our off function remember it's inside Firebase Jaz and we are going to call the sign out function that's all and we do that our state will change here in this case the user will be null so when we try to fatch users we are not going to have any ID so our current user will be null let's try I will click here as you can see we are on the login page if I refresh perfect let's log in as Jane and perfect of course our password is too weak but anyway it's just a test mode so right now using this user ID we can patch our chats here remember inside our database we have user chats and those IDs are our user IDs so when we patch our data here we are not going to have any chat but later we are going to add so let's see how to get this data but also when a user sends us a message we are going to update our chats immediately so basically we are going to fetch the real time data so instead of fetching data like like this we are going to listen our collection to do that we are going to be using on Snapchat method as you can see we can get real time updates to do that again we are going to be using document we are going to write here the collection name and the ID in this case it's going to be user chats and the ID will be our user ID and and after that it's going to return the data and since we are fetching a real time data as you can see we should create a cleanup function you know how to do that I'm going to copy this close everything here and open up my chat list first see I'm going to get my current user use user store why it's not importing okay let's just paste and after that I'm going to create here a user fact to whenever we run this page this component it's going to automatically fatch our data and after patching we are going to store it somewhere let's create one more State and I will say chats chats at the beginning is going to be an ampty array and here I'm going to create this on sub function and at the end I'm going to clean up just like that let's make it like this let's import them on Snapchat document and DB it's going to be user chats and we are going to pass here the current user. ID I'm not writing user ID because remember in our database we are storing them as ID and finally we can set our state set chats just like that in this case we should create here a dependency whenever our current user ID changes it's going to run again let's see chats I'm going to open my console we have the chats and it's an empty array so it works works so using those chats I can update my list here let's copy this actually let's remove here and right now I'm going to delete those items I'm just going to leave one of them and using my chats I can show my items for e chat return this D as you can see there is a warning because we need to add here a unique key and it's going to be chat. chat ID and here is going to be chat do last message but there is something important here as you can see we are also going to need this user but in our user chats we are not going to store our user information because if you store that and when the user changes their user information like Avatar or username we won't be able to see them to prevent this we are going to store here only receiver ID and using that ID we are going to patch our users using this collection in this case we are going to get the latest information of the user so what I'm going to do is after patching chats we are also going to get the user information so let's remove here and I will say const items it's going to be our chats remember it's inside document and data actually let's change this name I'll say response because when we fatch our user we are going to use document again to prevent any conflict I'm going to change this name and do chats and right now use using each chat I'm going to patch my user in this case it should be an async function because we are going to make a request and since we have a list here we can use promise all so I will say con promises items do map and for each item we are going to f users so again here is going to be async and remember how we are fetching data we are going to get our reference and using get document function we are going to fetch our data let's do that I will say user document ra and user document snap let's import this and here is going to be users and we are going to pass here item do receiver ID let's pass this here and finally it's going to return us our user let's say const user equals user snap do data by the way there's a typo and after that we can return all the ch information this item and also this user so I will say return everything inside the item which means our chat information and also this user so let's resolve this I will say con chat data wait promise all and let's pass it here and fine finally we can update our state here set chats and it's going to be chat data and also I want to show the latest chats first so we can sort them here so I'll say sort as you can see we can create here a compare function it's going to take two items and it's going to compare them here in our case we are going to check updated at times so let's say A and B and return B do updated at minus a do updated at if you don't know JavaScript sort you can check it quickly don't be confused there is nothing complex here of course there is no item right now so let's create our first chat using this button when I write any input here and click it's going to search for that username and if I click on this button we are going to create our first chat let's do that I'm going to close here and I will open up add user so using this form we can take this username and search for that user in the database so I will say handle search let's create const handle search event since we are using a form we should write here prent default otherwise it's going to refresh our page and after I'm going to get this username remember how we are doing this form data new form data I'll say C username form data doget and the username let's search for our user in this case it's going to be async try catch and this time we are going to need a condition to do that we are going to be using the query method as you can see we are going to create a reference we are we going to pass here collection name which is users and using the query methods we can search for any field inside that user in this case the username will be this username let's do that I'm going to copy this paste here let's say user ra I'm going to import this okay it's not coming let's change here okay let me import them quickly DB from Firebase JS and the others from Firebase fire store let's say user ref and the username will be our username after that we can get our data const C query snapshot await get documents and I'm going to pass here my query and after that if it's not empty we are going to update our user if query snapshot is not empty we are going to set our user let's create here user set user use Tate hook and at the beginning it's going to be null after that we are going to set this state here and it's going to be query snapshot do documents because we can have multiple items with this condition but in our case remember the username is unique so we are going to have only one item inside this array so if I say take the first item and return me the data it's going to return that user let's see actually I can directly write here I will say if there's a user show this do and here is going to be user. aatar if it doesn't exist use this one and here is going to be user do username Let's see we are Jane I'm going to search for John and there is something wrong again I forgot here R Target and here is going to be documents as I said it's going to return us an array and let's see I'm going to search and John is here so right now when I click on this button I'm going to create a new chat and also I'm to update the user chats because inside my documents we don't have any chat it's empty but as soon as I click here I'm going to update this user chats and we are going to pass here the chat ID the last message the receiver ID and updated at date before doing this let's create our chat I'm going to come here and I will say on click event handle at const handle at of course it's going to be an async function and here I'll say try catch and firstly I'm going to create my new chat to do that I can write here my reference chat ra collection I'm going to pass here my DB and let's say chats we don't have yet but we are going to create and it's going to include the created ad and all the messages of that chat remember user chats will be on the left side when we click on any user chat we are going to take the chat ID and search for our chats okay I'm going to create one more and it's going to be user chats ra let's add a new chat first await remember how we are adding document we are passing here our reference which is chatra and after our data the created ad will be Firebase server timestamp and the messages will be an empty array let's import this just like that but after that we are going to need this document ID I cannot reach it writing const chat it's not going to work firstly we are going to need our document reference and using that reference we will be able to reach this chat ID to do that I'm going to create here a new reference chatra document and I'm going to pass here my collection reference just like that right now I can use it here after adding this document we can reach its ID let me show you new chatra doid let's try I'm going to click here and as you can see this is our chat ID so using this ID I can update my user chats let's refresh here we have chats and inside created ad and messages so using this ID I can update my user chats we are going to add here our chat ID last message and other information so let's remove this one and try to update our user chats to do that I will come here and I will say await update document doc user chats ref and we are going to pass here the user chat ID which is the user ID and after finding that chat we can update the chat array to do that we are going to be using using array Union function it basically allows us to push any item inside our array and here is going to be chat ID which is new chatra do ID we don't need this console loog anymore and also we are going to add here the last message of course it's going to be an empty string we will not have any last message and we are going to have the receiver ID and it's going to be current user. ID but we don't have here let's import const current user use user store I'm going to import here and we can pass our user ID here and finally updated at again we can pass here server time stamps but if you are using array Union it's not going to work you cannot use them together so what we can do here is use a date so we are going to send the current date so in this case it's going to update the user chat and pass here our ID but we should do exactly the same thing for our user chat so I'm going to duplicate this this time we are going to update our chats so I will say current user. ID and this time it's going to be user ID let's try it's empty this is empty we don't have any chats let's try to add this us us again I'll say John I'll say add let's check our chat is here and if we check user chats you're are going to see that this ID is exactly the same ID and for the other user the receiver ID is different okay let's refresh here we have one item because we have a chat right now but we didn't update here let's open up chat list and here is going to be chat. user. username just like that and this Avatar chat. user. aatar if it doesn't exist use this Avatar PNG just like that and if we login as John John gmail.com one to six as you can see Jane is here right now when I click on this button I'm going to fatch my chat and we will be able to see all the messages of that chat after this use effect I'm going to create a new one because we are going to listen a real time data in this case I'll say onap remember how we are listening on Snapchat document we are going to pass here our DB and chats and we are going to pass here the chat ID for now let's paste this ID after we are going to be using State Management tool and take that ID dynamically but for now let's paste it and after that it's going to return us a response and using that response we can set our chat let's create one more use stage it Chat Set chat and I'm going to set this here response. data and after that we should write here the cleanup function return just like that let's import them I will just paste let's see our chat I will refresh and as you can see our chat is here so let's create another state and store our chat ID and also we can send the user information so we can use it here here and here let's do that I'm going to open up my library and create one more store I will just copy and paste and change the name and I will say chat store and here is going to be use chat store and I'm going to store here my chat ID at the beginning is going to be null the user will be null and also I'm going to store two more thing remember in our application we are storing the blocked array here we can block any user using this button or they might block us in this case we cannot send any information here and also if a user blocks us we cannot see the user Avatar and the user name so let's add them here also is current user blocked and let's say is receiver blocked at the beginning think they are going to be false and right now I'm going to write my action let's remove here and I will say change chat when we click on this item we are going to send the chat ID and the user information we are going to take them and using those information we are going to check if the user is blocked or the receiver is blocked blocked to do that we are going to need the current user from the user storage it's really easy to do that I'll say const current user use user store get State and I'm going to pass here what I want to fetch and it's going to be current user so using this we can check if the current user is blocked let's write here a comment and after we are going to check if receiver is blocked let's do that I will say if user dot blocked remember it's an array includes our user ID that means we are blocked so right now I can update my state I'll say return set let's copy here and paste chat ID will be this chat ID but we are not going to pass this user because as I said if we are blocked we cannot see the user information so let's do it like that and null is current user blocked true and it's going to be false so I can do the same thing here this time we are going to check our blocked array current user blocked includes the user ID if it is we can see the user but this time here is going to be false and here is going to be true and one more thing when we click on this button we are going to block this user or if we already blocked we are going to open that block so let's write here one more action and it's going to be change block I will say set we are going to take the previous state we are not going to change anything they are going to be the same but we are going to update his receiver blocked and if it's true it's going to be false if it's false it's going to be true so basically I will say take the previous state and is receiver blocked by the way there is something wrong here okay okay so let's call this action on our chat list oops jsx then we click on any div here we are going to call a function let's say handle select and we are going to pass here the chat ID remember it's here just like that let's create this function function we are going to take the ID actually we are going to also need this user so I'm going to pass the chat directly not ID and let's say async I said async because when we click on any chat here we are going to update our user chat we are going to add here EC field and it's going to be true because when we click that means we read our messages we are going to do this later but before let's call our chat store I'm going to come here use chat store and change what was the name change chat let's use it here we are going to pass the chat ID and the user in this case we don't need this hardcoded ID anymore instead we are going to be using our chat ID that comes from our chat store let's copy this paste here I will import this time we are going to need only chat ID here and using that ID we can patch our chat in this case of course we are going to need this dependency and let's see right now I'm going to refresh and as you can see there's a problem here because at the beginning our chat ID is null so we shouldn't see this page if you remember in our appjs if we have a user we can see all these items but right now I can write here a condition I'll say if chat ID show this chat component I can do the same thing here of course we are going to need our store that's import and it's going to be chat ID okay as you can see right now we have only this component but when I click here okay there is something wrong chat list I want to also get my chat ID and that's console lock okay at the beginning it's null when I click nothing is happening oh because our user is not blocked or this receiver in this case again we should set our state so I'm going to copy this chat ID user if we are not blocked and if the user is not blocked they are going to be false actually let's write here else if and else let's see right now I'm going to refresh I'm going to click and as you can see our chat is here and we don't have any message let's use those messages to show those items I'm going to come here and using this chat I can show my messages here right now I'm going to delete all those messages actually let's leave only one message here in this one because there is an image and I'm going to wrap here and I will say chat do messages. map for each message we are going to return this D in this case we are going to need here a unique key we can use it created at date and if there is an image we are going to show it if message includes image show it here and here is going to be message text and here is going to be message do created at but if we do this it's going to give us an error I'm going to leave it like that for now after we are going to update I will click okay let's write it like that and right now let's try to add a new message when I write something here and click on this button we are going to send this message to our chat collection remember we have a text State here we can use it I'm going to come here and create here on click event handle send firstly if there is no text we are not going to do anything if it's empty or let's write it like that they are going to say return don't do anything and after I'll say try catch block if there's an error console lock in this case here is going to be async and await update document that will pass here Doc and my DB collection name will be chats and I'm going to pass here the chat ID remember it comes from our store and after that I can write here what I want to update remember inside chat we have messages and it's an array and you know how to push items we are going to be using array Union so I will say messages array Union and pass here the sender ID is going to be our ID current user okay we don't have let's create quickly use user store and current user I'm going to use our ID here text will be text and the created ad will be new date and after there is one more important thing here when we send a message we are going to update our user chat because remember inside the user chats we have the last message and also as soon as we send the message the seene field will be true but the other users will be false so the other user can recognize that the chat is UNR and the user clicks on this item only that time his scene is going to be true to do that let's get all our chats user chats const user chat ra doc DB user chats and I'm going to pass here my user ID and let's get the snapshot await get document and our reference here and remember if it exists we are going to get the data let's say const user chats data snapchat. data okay right right now we have all our chats and now I have to find exactly the same chat that we are writing and after finding that chat we are going to update its last message and SE by field to do that we can find index of that chat let's say const chat index user chat data we have the chats array and I will say find index and for each chat I'm going to search for its chat ID and it should be equal to the chat ID right now we know which index number we should update user chat data and the index number here which fields we are going to update is going to be last message and we are going to write here our text and one more and is scen will be true because we are sending the message and finally one more and is going to be updated at date we are doing this because we are going to see the latest messages when someone sends a message is going to be on the top of our chats so let's say date do now and after that using the information we can update our user chat so I will say await update doc we are going to pass here our reference and chats will be user chats data do chats but again we should also update the other users chat when we send a message we are going to update the latest text updated ad dat but this time it scene will be false so we can show here any indicator like a background color so user can understand that it's a new message so instead of writing them again and again I can write here the user IDs and create here a loop let's say const user IDs current user. ID and and also user. ID okay it's not here like that and using this array I can run exactly the same thing and update the other user let's say user IDs for each async I'm going to take the ID and for each ID I'm going to run exactly the same thing and this time here is going to be ID and we are going to need here a condition if ID equals current user. ID it's going to be true if it's not it's going to be the other user in this case is scen will be false okay let's see I'm going to write anything hi I will send as you can see our message is here but we cannot see the last message there is something wrong if I refresh the page okay it's not here that means we couldn't update user chats because here I forgot writing do chats remember inside user chats we have the chats array and inside that array we have the chat information and here is going to be lowercase I hope everything is all right let's see test I'm going to send and as you can see it's here this is our chat message if we check our user chats this is our user ID is seen is true and this is the other user ID is seen is false so using this property we can update our item background let's do that I'm going to open up chat list and I'm going to write here an inner style and I will say background color if chat is seen it's going to be transparent if not let's say this blue color I'm going to save as you can see it's transparent but here it's going to be blue but when I click here it's going to be true again to do that we are going to update our user chat we have handle select here we can update here let's copy this paste here user chats it's going to be current user. ID and after finding our index number we are going to update is seen and it's going to be true I can delete here update but actually we don't have to fetch this data we are on the list page we already have our chats here but also we have the users what I want to do is I want to get all my chats without this user in this case we don't have to patch all the information again to do that I will say const user chats chats. map and for each item I'm going to eliminate the users to do that let's destructure them I will get the user and I'm going to spread the rest of the information and it will come from our item right now our chats are here user information is here I'm going to return this rest after that using this array I can find my index number con chat index do find index for each item we are going to check their chat ID if it equals our chat ID remember it's here right now I can use my is SE field user chats the index number is seen and it's going to be true right now I can update my user chats so I will do exactly the same thing here user chat that's our ID and I can say try catch here await update the reference and the data I want to change and the chats will be user chats and finally we can update our chat I'm going to save and right now I'm going to refresh if I click as you can see its color has changed if I refresh the page it's not blue anymore okay perfect so what about image when I click on this button we we will be able to select any image and we are going to show it here and again we are going to store that image inside use State and when we click on this button we are going to use our upload function and take the image URL let's do that I can close here open chat again and I'm going to create my image State image set image remember we are going to need the file and the URL and let's remember our login page when we update our file input we are running this function I will do exactly the same thing here let's write it here and this time I will say handle image and here is going to be set image and let's call this function inside our input of course we don't have any input yet let's create it's going to be a file and remember we are going to need here an ID and I will give an inner style and I will say display none and let's make this label ID will be file so when we click click on this image it's going to run this file input and I will say on change and it's going to be handle image we can have any image or we can also send only text to do that I'm going to write here a condition let's create image URL at the beginning is going to be null and I will say if we have an image we can upload this file and change this image URL so I will say await remember we have an upload function and we can pass here the image file and it's going to upload our image in this case we are going to have the image URL and I can write here a condition I will spread my condition here I'll say if there's an image URL the image will be image URL so if it's null we are not going to have anything here so this expression will be empty it's not going to send anything but if it's not null the image of this message will be the image URL that we have uploaded here and finally after sending our message we can update our image again file will be null URL will be an empty string and also I'm going to reset my text set text and it's going to be an empty string again and right now when we select any image we can show it on the center D we have the message div and inside text and we can show our images here so I can do exactly the same thing here I'll say message and it's going to be our message texts and inside image. URL of course if it exists so let's write here a condition let's see when I click here I can choose any image and it's here and if I write something here test image and sent and as you can see this is our text and image and this is the latest message if you check here you can see that we have a new message nice picture it's immediately here but there is something wrong we forgot to change this message class name so I'm going to write here a condition I will say if message do sender ID equals current user ID it's going to be message on if not it's going to be just message just like that response and it's here so what about blocking user if you remember in our storage let's open up chat store we have change Block action here we can use it let's open up detail and here let's say on click handle block let's get all these information from here and also our current user I'll just copy and paste just like that let's import using this user I can change my user information user. Avatar if it doesn't exist use Avatar PNG I'm using question mark because remember if we are blocked it's going to be null and I can do the same thing for the username oops here is going to be username just like that and here okay okay perfect by the way again let's change here inside chat user do username just like that when we click on this button we are going to run this function and it's going to change is receiver blocked firstly as I said if we are blocked the user will be null if it is I'm just going to return we are not going to do anything if not we are going to update our database so I will say async try catch wait update we are going to pass here our reference let's create here const user. ra document we going to pass here R DB and the collection name users and we are going to pass here the current user ID and here we are going to update our user and we are going to update the blocked array remember it's inside user and I will say if is receiver blocked we are going to remove to do that we are going to be using array remove and let's remove the user ID if it's not blocked this time we are going to block this user using array Union and finally if I everything is okay we can change our block just like that and right now I can write here a condition if we are blocked or the user is blocked we can show different texts so I will say his current user is blocked you are blocked if not we are going to check the receiver is receiver blocked this time user blocked if not if no one is blocked we can say block user and again using those values I can disable here and this button let copy this and paste here I'll say disable if current user is blocked or is receiver blocked I can do the same thing for my input here let's give a class name for the sent button I will say if it's disabled make this a little bit softer like that and the cursor will be not allowed I will do the same thing for my input and of course we are not going to have any background I will refresh choose my item here I will block user as you can see user blocked and we cannot write anything let's change this placeholder if they are blocked right here you cannot send a message if not type a message just like that let's check the other user okay we can see the image and the username but if I click here as you can see it's not here anymore because we are blocked and we cannot send any message so let's open up the chat list and here I'm going to write a ition I will say if chat user blocked includes our user ID current user ID we are going to write here user if not the usern name again for this Avatar if we are blocked we are going to show avatar.png if not it's going to show the user Avatar and if it doesn't exist again it's going to show our PNG just like that okay the last thing we can do we can search for any user here to do that I can create here one more use State it's going to be our text input text let's say input set input and whenever we write anything inside this input I'm going to update my state let's say on change take the event and update our input event Target and value and after that we can filter our chats let's write it here const filtered chats chats. filter get e chat and check their usernames user do username I'll say to lowercase and it's going to include our input again let's say to lowercase right now instead of chats we can and use filter chats just like that of course includes not include okay if I write anything here as you can see it's not here but if I say John it's going to be here okay it works so this is our application of course we can add some more features we can show some more details or those images but if you understood this tutorial it's going to be really easy for you if you have any problem or error you can check the GitHub repository I will try to update okay right now we can deploy our application to do that I'm going to open up my hostinger panel as you can see this is the IP address of our server so if you have any domain don't forget to redirect that domain to this IP address and after doing that let's click here and access our Cloud panel this panel is really easy to use you can add all your applications and websites using this panel let's add a site as you can see you don't have to install anything from scratch you you don't have to make any enginex configuration you can directly create a nodejs app using this button I'm going to add here my domain name chat. lad you can add here any port number it doesn't matter and this is our site user when we connect to our server we are going to use this name let's create our application okay it's ready let's click here and right now now I'm going to install a free SSL certificate using this tab let's encrypt to do that of course you have to make your domain configuration as I said you have to use your server IP address I will create and that's all as you can see we didn't even use any piece of code right now you can build your application and add your files to server using file manager but if you make any changes on your application in the future instead of doing this again and again you might want to use GitHub push your project and whenever you make any changes you can directly update your application on your server so let's push our application but before remember we are using an EMV file make sure that you are hiding this file using G ignore I'm going to write it here EMV I will save and it's ready to push I can terminate my server we don't need this anymore I will use contrl C and I'll push my application to my repository so I'll will say get in it if you get an error here make sure that you removed your dot git folder first and after create again using git in it after that I'm going to add my folders and files git add and dot let's commit you can write here any comment okay these are all the files that we are going to push to GitHub repository so I can add my GitHub repository here git remote add and my URL this is going to be your url if you don't have have any branch you can directly push it but remember I have the starter Branch so I'm going to create a new one get check out branch and the branch name so I will say completed let's push get push origin and the branch name okay right now our project is in this repository using our GitHub account we can build our application on the server so let's connect to our server to do that I'm going to open up my hostinger panel and SSH access using this IP address I can connect to my VPS to do that we are going to be using our local terminal firstly we should create an SSH key let's open up our terminal you can use any terminal you want let's come here right now I can create my key using this command by the way you can find all these commands in the description below I'll enter you can give any password here and our key is ready let's copy this using this comment and don't forget this URL should be exactly the same URL here if I enter it's going to copy my SSH key right now I can paste it on my hostinger panel I will come here and choose SSH keys and I'm going to add my key using this button let's give any name and I'm going to paste it here like that that's it it's going to take a while and after that we are ready to connect to our VPS okay it's ready let's remember our address I'm going to copy this that's clear and I will say SSH root and my IP address I will say yes and we are connected remember we created here our site we are going to find this folder and upload our files so I will say sudo Su Lama chat let's see what's inside okay let's get back to the main folder cdhd Docs let's see okay our site is here let's open up right now I'm going to install my files using git let's check if we have git or not okay we have we can see the version using this commment so as you can see everything is ready to use we don't have to install anything I can directly upload my files using git I will say get clone I'm going to clone my Branch so I will say single Branch again if you don't have any branch you can directly paste your url I'm going to use my completed Branch I will paste my URL I'll install everything here so I say dot and enter let's see okay all our files and folders are here right now I can install my libraries mpm in install as you can see mpm is ready to use we don't have to install okay if you remember we don't have our EMV file let's create nan. EMV let's paste our API key and I'm going to save this using contrl X I'll say Y and enter let's see okay our libraries are here let's check again our EMV file okay it's here so we are ready to build our application to do that I will write mpm run and build right now we can serve our application to do that I'm going to install serve and pm2 so using those libraries we can serve our application but before let's check our folders and as you can see after building our app we have this folder here and that includes all our images JavaScript and CSS files and index HTML right now I'm going to serve my application using this folder to do that I will say pm2 serve and the folder name and right now our application runs on port number 8080 if you remember when we created our application here we said a port number so it should be exactly the same number let's see our website right now I'll say chat. lamad and our application is here let's login and perfect let's test test from website and it works our message is here we can block this user log out let's log in again as John and the color is blue because we didn't read the message but if I click we can see our message here and if you check your connection you are going to see that you have an SSL certificate so creating not Jaz applications are that easy guys if you make any changes just push it to your GitHub repository and build your application using your server this is the easiest and the cheapest way to deploy your applications okay so we finished finished our project I hope you liked it if you learned something new today please like the video you can support lamade by using the link in the description below or by joining the channel don't forget to follow lamad social media accounts I hope I'll see you in the next tutorial goodbye
Info
Channel: Lama Dev
Views: 102,370
Rating: undefined out of 5
Keywords: chat application, react firebase, chat app, react chat app, firebase chat app, realtime chat app, react, react project, react tutorial, chat app tutorial, firebase v9, private chat app, whatsApp clone, lama dev, react.js
Id: domt_Sx-wTY
Channel Id: undefined
Length: 195min 8sec (11708 seconds)
Published: Wed Apr 10 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.