🔴 Build a Realtime Chat App with Firebase | Authentication | Expo Router | React Native Projects

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everyone welcome back to code with Nomi and today we're going to learn how to build a fully functional app we're going to implement authentication system and a messaging system in react native and for that we're going to use Firebase we'll be using Expo router latest native wind 4 Vector icons looty animations and so much more on top of that we'll be also making our app responsive so that the looks good on all the devices so if you're new to export outer or react native then this is a good s to master your skills in react native and uh with that said let me show you the demo of the app so when you start the application the first thing you'll see is the sign in and sign up pages and I'm currently running the app on IOS and Android devices so you get the idea of how the app is responsive on both the devices and on the sign up page I've already implemented the keyboard avoiding view so if we have a lot of inputs on our screen that won't be a problem our keyboard will not be covering the inputs so you can scroll through all the inputs so let's go ahead and create a new account John Weck Wick at the gmail.com and let's create a password and for the L field we're going to add a link of the image I've already opened an image so so let me just copy and paste the link for that and hit sign up okay so we are signed up and the first thing we'll see is a list of all the users in the application and on the header if we click on our icon we will see a context menu where we'll see two options to visit our profile or to sign out the application so let me sign into my other account and see how the messaging system works let's put the password and hit sign in and we're logged in so we'll get all the users in our application so here you will notice one thing we also see the L message and the time of the message that's because if you already have conversed with the user you will see the last messages and the date of the message but if you haven't you will see a suggestion saying hi to start the conversation so if I open a user we will see the message history with that user and if we have a lot of messages in a chat history and we click on the type message this will push all the messages to show the input on top of the keyboard so let's go to our new user and send some messages uh let's say hi and you will notice as soon as I click on the send icon this will update the message in both the apps so we got the message in message history and we also got updated our chat list and we are seeing the last message and the date of the message so let's click on it and we got the message history now let's send another message from John Wick hey man how are you and as soon as I click on the send icon this gets updated on both the apps so let's send some more messages uh let's see what's going on and if I send this appears on the other side um let's say getting bored at home what about you and hit send and we got the message so let's reply same here let's send an emoji as well um let's send this one and hit send and we got our message so this is how our chat system is working and we can go back and see all the other users and we can chat with them I also implement Meed the keyboard avoiding View and it works great so let me sign in with another account and show you what I mean let's sign in with Tom add password and hit sign in the keyboard avoiding view works really great in sign in and sign up but one thing I really like is when we are in a chat where we have a lot of messages and if you click on the input it will push all the messages and it will still show the input on top of the keyboard I really like how smooth it does that and it's also implemented on the Android side so if you open the same chat and if I click on the input it will push all the messages and still show the input and the last thing to show is this context menu which appears on top of everything I haven't implemented the profile part uh which I will leave up to you guys so this was a brief overview of how this application is going to work and if you are interested to build this application we'll be building this application together together and if you find this video helpful do like the video and subscribe the channel because this really helps the channel to grow and uh without further wasting any time let's get started and build this application so first of all you need to go to Expo website and on the sidebar you will see the installation tab just click on it and here you'll find the quickest way to install an expo app with tabs and if you scroll down you will see a manual setup process as well but if you're not going to follow this because this is very lengthy we will stick with the quick method so let's just copy this command and open the terminal let's paste it here and this is going to ask us about the application name let's name it Firebase chat and this is going to install the application for us so let's wait okay it's finished now we can close the terminal and open the project into vs code I've already done that while it was was being installed so let me just drag the vs code here let's make it full screen let's also drag my iOS simulator and let's adjust them both in one window like this now first of all what we're going to do is run our application to see how it looks like so let's open the terminal and write the command npm run iOS this is going to run the iOS version of our app and here is the app directory of our application we have app assets components and the constants we'll probably remove all of this code because we're going to build this application from scratch so let's just wait okay so the application is running and as you can see we have two tabs at the bottom and if I click on this icon this should open a model so this is what you get when you install a new Expo router app so let's remove all of this code let's select all of these tabs and remove them and let's keep our assets and we're not going to use the components all of these components so let's just remove all of them and uh let's keep our constants for now so let me create the first component in app folder and the export works on file based routes so if you are not familiar with the X Expo router then I'll suggest to watch my other video on Expo router so let's just refresh this error will go away okay so we have our first component and before we start designing this component we need to install native in to design our application so let's go to Native wi and Native wi basically uses Tailwind CSS and we're going to install the native wi version 4 which is the latest version so here is their documentation and you need to click on export outer in the sidebar and we're going to follow all of this to install it and set up this into our application let's stop our server and uh first we need to install all of these libraries let's just copy this and paste it into the terminal and then we need to install this command and because I not using react native CLI so I don't need to do this then we're going to run this command to create a Tailwind configuration file so let's just copy this command and paste it into the terminal and this has created a delin configuration file we're going to change the contents of this file so uh let me just copy the content and the preset property let's copy this and replace this into our configuration file and this content property basically holds a list of all the directories where we can use the Tailwind classes so for now it's pointing to the app directory but we're going to use the Tailwind classes into our components folder as well so let's just copy this and change this to components as well and let's save this and then let's see what's the next step so next we're going to create a global. CSS file into our root directory and paste this inside it so let's create a file global. CSS and paste the contents let's say save this and let's see what's the next step next we're going to add the beel preset and here we see the presets and the plugins and I think we need to add both of them so let's just copy the presets property and go to our wable configuration and replace the presets here and uh we will need to update the plugins as well we already have router SL so let's add the plugin for reanimated okay that's done okay next we're going to modify our metro. configuration file and if you want see this file into your project just run this command and Expo will created for you so let's see what we're going to change let's go to metro. configuration file okay so this is the file and we need to import with Native wind component like this and we need to export the configuration using this so let's copy this and paste this here and this should point to the global. CSS Pro uh file that you just created so next we're going to add a layout component inside our app folder and we're going to import the global. CSS file so inside AB directory let's create a root layout file and let's create a functional component and inside this component we're going to copy the slot component and we're going to export it a slot component is basically uh think of it as it it renders your children properties so because we using it in a layout component this is going to render all the children in that layout so let's just export that and we also using our global. CSS file here so that's done now let's start our project and see if we have successfully implemented native wind let's wait for it okay we see some warnings uh let's run it on iOS let's press I and it's building and we got this error um unable to resolve slot maybe we need to create a layout function and then return a slot from it so let's create a layout function and here we'll just simply return the slot component like this and let's save this and reload okay so that won't fix our problem uh let's just undo all of this and just use that in here so inside our view we'll just render the slot component like like this and let's save this and let's reload um same error again maybe we need to import it like this and uh let's reload okay so that error is gone but now we see another error and that's because the export aitor doesn't like the version of reanimated installed into our project it requires a different version of reanimated and when we ran the project we saw a warning suggesting uh run this command to fix this issue so what we're going to do is copy this command and run this into our project and this is going to fix the situation so let's wait a bit okay it's done now let's run our project now hopefully everything should work fine and we don't see any warning or error let's run it on iOS and it's building so the application is running and we don't see any error that's a good sign and on the top we see a text coming from our index component so let's go to our index component and it says home uh we need to add a little padding top so that we can see the text clearly uh let's add a pedding top of 40 and save this now we can see the home now now we should be able to use the Tailwind classes for our components so let's add a class name of background red 200 let's save this and it didn't work um maybe we missed something uh let's go to our layout file okay yeah we need to import the CSS file I think we mistakenly removed this when we were fighting with the slot component so that's imported so when I save this you see the background color changes that means our Tailwind class is working now so now let's make this text bigger using text 3 XL class now the text is bigger now let's also move it to Center using text Center class and it's working so now we no longer need this style property so let's remove all of this and we can add a padding top using padding top of uh let's say 20 so the classes are working now and we have successfully implemented mented the latest version of native wind into our project so now we're going to add authentication into our project and for that we need to go to Expo website and on the sidebar you will see under the reference the authentication option just click on it and now we're going to follow this process to implement o into our project and uh we're going to have a file structure just like this layout and sign in and then we're going to have an app Group for our protected routes so the first thing we're going to do is add an authentication context and if I expand this first step you will find they have implemented a context and we will save our states and all the functions in this context they're using the loading and session data so then we're going to use local storage to preserve the user token and then we can use this session provider into our layout file and we will be using the loading and session data to check if we want to show the loading or we want to redirect to sign in or homepage so we're going to have a very similar structure just like this I know all of this sounds a bit confusing but once we start implementing you will see this very easy so the first thing we're going to do is add our signin and sign up pages and we're going to create these files in our app directory so let's create sign up as well let's create a functional component and we're going to change the names to Capital signup same goes for the signin component as well okay so now we're going to create a folder which will be a group of routes for our protected routes and I will name it app if you want to learn more about file based routes and how groups work in export router then I have another video on expore router I'll suggest to watch that video before you start this project so all of your questions will be answered in that video so now let's create a layout file inside our app Group let's leave it like that for now now let's create another component home which user will see after he logs in so let's create a component and rename it okay so currently we have this index page which is shown by default and uh we're going to change this to start page and we're going to show a loading State here so let's rename this to start page basically the idea is until we get the user from local storage or from Firebase we're going to show a loading state so that's why we going to turn this into a loader let's add Flex one justify Center and instead of this text we going to show activity indicator which is a built-in component size would be large and color will be let's say gray let's save this um I should should see the loader uh let's reload the application and see okay so we can see the loader but it's at the very top uh maybe we need to add item Center as well um why is it not centered let's go to layout um yeah we need to add a flex one to this container so the reason why it was not centered because it didn't have full space now we added Flex one so now it is centered okay so next thing we're going to do is add o context into our project so let's create a folder in root directory and inside this folder let's create o context file okay so first we going to add o context and let's create a variable o context and we're going to use the function create context from react just like this and then we going to create off context provider context provider and this will receive all the children components because it's going to wrap our application and inside this we're going to use a state for user which will be null by default and we're going to use another state is authenticated basically we'll use this state to redirect the user to sign in or to homepage so our authentication system will depend on this state and I'm going to set it to undefined and uh I will explain later why I did that now next we going to add a use effect hook without any dependencies so that it acts as a component did Mount function and we're going to use a function inside this but not now we'll be using that function in future uh the function will be on All State change that is from Firebase and uh the idea is basically here we will get the user which will be authenticated and based on that user we will redirect the user to sign in or homepage now let's create some o functions that we will use later and login function will receive email and password and we're going to make it async because we're going to make API calls let's add try cach blocks as well so that if we catch any errors we will show that to user let's just copy this for our log out function as well and we won't receive any parameters so let's remove them let's copy this login function one more time for our register function and this function will receive email password and additionally it will have a username and a profile URL as well okay great now we're going to return our context provider so let's add context. provider and we will render all of our children because this is going to wrap our application and here we're going to provide a value which will be all the states and all the functions that we going to receive in those children components so we have user authenticated login register and log out okay all done now we're going to create one more hook to use this context provider in any component so let's create another function use Au and this will use a use context Hook from react to use this context values and we need to pause our off context to this hook and if we don't get the values that means this Hook was called where the component was not wrapped inside our provider so we're going to throw a new error saying use o must be wrapped inside an authentication context provider okay and if we do get the values we'll just return the values from here okay this is done for now we'll come to this component later so now we need to go to our root layout file and here I'll just Implement a new layout because this clout needs to be wrapped inside our context provider so let's create our new main layout and here first we'll use our is authenticated State and we need to call our use o function from our context file so let's import that just like this next we're going to use another hook which is called use segments and this will return us the segments value so basically this hook will return us an array of all the segments in current route so if uh let's say I'm in index route and this will give us an array with a string of index and same goes if we have routes in multiple folders or directories this is very important because let's say if user is authenticated and he's on sign up page where he shouldn't be then we can redirect the user on homepage so that's where it is very useful now let's create a use effect hook and this hook will be triggered every time our All State changes so this will be dependent on this state and here we will determine if the user is authenticated or not and we'll do this logic later but uh now we need to return the slot component which will render all of our children so let's return a slot component just like this okay so this is done now we need to create another component so let's change uh this component to our uh let's say root layout because we're going to use a provider and wrap this main layout with that provider so let's add Au context provider and this will import the context Provider from our file and inside this we're going to render our main layout we are doing this because we need to use the use o hook inside a provider that's why we did that okay so our authentication system is totally dependent on this state is authenticated and this state will be responsible for redirecting the user to home component inside our app group or to redirect the user in sign in component when it's false but when it's undefined we will show the user a loading State and we have the loading State as a default component so when it's true we will show the home component and when it's false we will show the signin page but when it's undefined we will keep showing the loading state to user so here we will make a check if the type of is authenticated is undefined we will return and then we will check if user is in app group or not we will check the first segment and if it equals to app group that will mean user currently is in app Group now we have two values in app and is authenticated and we can use that to see if uh user is authenticated and user is not in app group that means we need to redirect the user in home so we will have a condition for that we will also check if the user is not authenticated then we need to redirect to signin page but let's add a comment here first we need to redirect the user to home so that we don't forget it later so when user is authenticated and it's not in home we need to redirect to home otherwise if user is not authenticated then we can redirect the user to signin page so let's add a comment redirect to sign in now we're going to use the router to redirect the user wherever we want so for that we we're going to use use router Hook from Expo router and uh using that we can redirect but I'm going to use the replace method so that user won't be able to go back to this loading State here we will replace it with home component and if user is not authenticated then we're going to go to the signin page okay let's save this now you won't see any change because if authenticated state is undefined so if I go to our context um here so by default you will see we have undefined value for is authenticated State now let's say here we have some logic that will get the user after 3 seconds so for now we'll use a set timeout method so let's say after 3 seconds we will get the user and we will set is authenticated to true and if I save this and uh we wait for 3 seconds we should be moving to home screen okay so now we are in the layout it says layout uh why it says layout so let's go to app Group and in home um it should say home let's go to layout uh okay so we need to return a stack component here that's why it was showing layout okay now we can see our home component so now let's go back to our off contacts now if I refresh the app we will again see a 3 seconds R then we will move to home screen now let's say user is not authenticated and this will be updated to false and when I save this we will again wait for 3 seconds and it will hopefully move to signin page okay we can't see the sign in text clearly so let's go to sign in and add some padding top let's say padding top of 20 let's save this now we can see sign in page so if I refresh we will again see 3 seconds wait and then sign in okay so now we have an authentication system where if the user is authenticated he will see the home screen otherwise he will see the sign in screen so later on when we Implement Firebase o we won't have to do a lot because all the basic setup is already done I'm using this set timeout method so that we can see the loader but if I make this false and remove this set timeout method we will immediately see the sign in page now we're going to start designing our signin page and before we design this page I need to install some of the libraries first starting with the react native responsive screen we're going to use this library to make our app responsive this Library uses the dimensions under the hood so this will provide us with HP and WB methods and these are stands for height percentage and the WID percentage of the current device so if I give 80% of WP that will mean 80% of the current device width and we can use this for making a font size responsive and we will have a design something like this now let's just copy this install command and open the terminal let's open another terminal and paste it here okay that's done now we can close the terminal and we can use this Library into our project so let's just copy the import statement into our component and before we start using this I need to install another library for our icons and the library is Expo Vector icons and I really like this library because it provides various types of icons and this is a basic usage of how we can use the icon and if we click on one of the resources this will take us to where we can find all the icons and here I can search all the icons we have and design ionicons and a lot of other icons so I'll just open it in another window and and let's just copy this command to install it paste it here and it's done now let's just refresh the app to see if we have any errors okay great now let's start designing and give this container a class of Flex one so that it takes a full space and inside this we're going to use a component to change the colors of our status bar we're going to use stus bar from Expo and we're going to add a style of dark like this and let's add another container and give this a clo of Flex one and a gap of 12 and inside this we're going to add a sign in image at the top so let's add another view and to make it centered let's add a class name of item Center and in inside this let's import the image component from react native now we're going to use some of the images throughout the development of this app so let me just copy and paste all the assets into images let's just paste them here and these are some of the images that we'll be using while developing this app so you can find all of these into this GitHub repo now let's just copy the login image that we just copied we need to go into s sets images and we need to use the login.png image and let's save them um none of these file exist maybe we misspelled the name okay it needs to be images we misspell the images okay we can see the image now for the height of this image I'm going to use HP function from our responsive library and if I give 25% of HP that will mean 25% height of overall height of the device and let's add resize mode to contain now we can see the image but we have this anage conflicting with our content so what I'm going to do is add a little padding top to this View and let's use HP of 8% now it looks good now let's add a padding horizontal as well let's use WP method and that will mean 5% width of the overall width of the device we will see this horizontal padding when we add a Content at the bottom so let's add a view and give this a class name of Gap 10 and let's add another text view inside this this will say sign in and you can see we added a horizontal padding now to make this text responsive on all of the devices we're going to use responsive font size of HP4 that will make sure it is responsive on all the devices let's make our text bold using font bold class and tracking a bit wider using this class and let's make it centered okay now let's change the color of this let's use the text neutral of 800 okay this looks good now under this text we're going to use a form and we're going to add all the inputs so let's add a comment and a view this will be a wrapper for our email input so I'm going to give it a height let's use HP of s and let's add a CLA name because we're going to use an icon and the input inside this so I'm going to make it Flex row and a little gap of four Bing horizontal of four and for the background color let's use neutral 100 item Center and to make them rounded let's use rounded to excel okay now here we're going to use an icon from our Expo Vector icons so let's go to the documentation and we already opened the list of all the icons so here you can search any kind of Icon I'm going to search for mail icon and you can find a bunch of male icons that you can use but I'm looking for the one from octicons so let's see where it is okay here so I'm going to use this icon from octicons so let's go to our app and here if I just type octicons this will Auto Import and here first we need to provide a name of the icon which is male and then the size which will be HP 2.7 and the color let's just use gray and let's save it okay it looks good uh maybe we need to reduce the Border radius let's use rounded Xcel okay great now after this icon we need to use a text input so let's import the text input component and uh we need to use the responsive font size so let's add a style and give this a font size of hp2 and after this let's add a class name and uh let's use flux one so that it takes a full space in our container font semi board and the text color should be neutral 700 now let's save this and uh we have the input but let's add a placeholder placeholder will be email address and let's add a color for this placeholder which will be gray and let's save this now we can see the placeholder and it looks good now we're going to copy this one more time for our password input field as well so let's copy this whole View and we will just change the placeholder from email address to password and let's save this um we need to reduce the space between these two inputs so let's add another view and give this a class name of Gap 4 and we will just move these inputs inside this to reduce their spacing let's indent them and save them okay now it looks good so we already already have the email icon but now we need to find the icon for password let's go to our Expo Vector icons and look for lock icon uh I think we can find the lock icon in octicons so this is the icon that we're going to use from octicons uh let's replace the name to log and save this now we have both the icons right now after this view we are going to add another text at the bottom that will say forgot password let's let's add a view and give this uh class name of Gap three and we're going to move this last input inside this so that our lost input and forgot password text have a little Gap and inside this we're going to add a text View and inside this we are going to sa forgot password okay we can see the text now to make it responsive let's add a style and give this a font size of HP 1.8 and it should be on the right side so let's add a class name to make it semi bold text right and it's on the right side now for the text color let's add a text neutral of 500 and let's save this um it's not applying let's change this to 400 okay it is working so let's changed back to 500 maybe it was some issue with the cache so the Gap is also not working we applied the gap of three for both of these items so let's change it to four and let's save this it is working let's change to three okay I think there was something wrong with the cache now it's working now after this text we're going to add a submit button at the bottom so let's add a button after this view let's add a command submit button and let's use the touchable opacity and inside this let's add a text view let's give it a responsive font size of 2.7 HP 2.7 and let's add a class name to make our text white fonts board and we need to add the letter spacing so let's add tracking wider and let's add sign in text inside this you won't be able to see it because the text is white so let's add a background color and we're going to use the background of indigo 500 and let's save this um let's refresh the app we should be able to see it okay so here we have our button so let's add some more properties we need to make it rounded Excel justify Center and item Center let's save this now I need to add a height to this button so let's add a style and give this a height of HP 6.5 let's save this and it looks great so after this button at the bottom we need to add a text that will say if user haven't signed up then we need to provide him a button to go sign up here so after this touchable opacity let's add another command sign up text and let's add a view and give this a class name of flex row we're using Flex row because we are going to add two text properties in this view so let's add a text View and let's say don't have an account question mark and after this text view we're going to say sign up and if I save this you will see sign up we need to have a little space so let's just add a space after this question mark okay great now let's add a responsive font size to both of these text views so let's select both of them and add a style property add a font size of HP 1.8 and let's add a class name to make them board let's add font semi board and text neutral 500 for the color of the text and save them okay we need to make our sign up text a bit Bolder and for the color let's use Indigo 500 to make make it stand out okay great now we need to be able to move to the sign up page when we click on this and for that we need to wrap it in a pressable component so let's add a pressable and we need to move this text inside this and to be able to move to the next screen we need to use the router so let's declare our router and we need to use the use router Hook from Expo now let's add an onpress method on this pressable and using our router we need to push the route name which is sign up and let's save this now if I click on this button we should go to our sign up page and it's working now let's refresh and the next thing we're going to do is store our email and password Valu somewhere and I'm not going to use state variable for that because every time State updates it renders it reenders the whole page so I'm going to use the reference to hold the values for email and the password and currently I'm going to use the empty string for both of the values and then we're going to have another function to handle the login process and this will be triggered every time user clicks on the signin button and this is going to be an async method method now when the value changes inside this input we're going to update the current value of the email reference so let's change email ref. current value to the value given by this component and let's copy this for the password as well using this method won't render every time user presses a key so that is very useful now let's add our handle login function on this touchable opacity now every time user presses on this button we need to check if we don't have any values inside the references we need to show a message so let's check if we don't have any value in the email reference or we don't have any value in the password reference then we going to use alert from react native and we're going to show the user with a title and a message title will be sign in and the message is going to be please fill all the fields okay now we need to return from here and after this if we have both of these values then we will begin the login process so let's just add a command login process and let's save this now if I click on this button we will see this error because I haven't added any value and if I leave one field blank we will still this get this error and let's add both okay we need to change this to secure text entry so let's add a property secure text entry that will hide our password okay great now when we are signing in the user we need to show a loading State instead of this signin button and for that we're going to use Lo animations to show a loading animation so let's go to our browser and and we need to install this package ly react native and if I scroll down you will see a very basic usage of how we can use a ly animations into our app so let's copy this command and install this first into our project let's paste it here and for the animation I usually go to a website ltif files.com you can use any other resource where you can get these Loy animations but I'm going to use this one so if I scroll done here you will see a comparison about how ly animation is better than GIF animations so I recommend using ly animations and let's discover some animations I'm just going to show you how you can download the animation from this website so just search for uh loading animation here you can find a bunch of animations just click on the one that you like so for example let's use this one so if I click on this first I need to save it into my workspace to be able to download it so let's just save it and this will open this animation in an editor and at the top you will see the download icon so you can download the loty Json file from here I've already downloaded a loading State animation from this website and I've copied that animation into my assets so now we need to use this Library into our project and and this is the basic usage of this Library so first we need to create a component for our loading stat so let's create a loading file and create a functional component now the size of this loading state will be provided from the parent component so we're going to set the height as the size which will be passed to this component so let's use that and let's give this an aspect ratio of one now here I'm I'm going to display the ly View and we need to import the ly view first so let's just copy this import statement and let's add our Loy View and give this a style of Flex one and for the source I've already added a loty animation file into our assets so let's require that into our assets images and the file name is loading. Json and we need to add some properties like auto play and loop this will make sure this animation plays in infinite Loop now we can use this animation into our signin component so let's go to sign in and we're going to use that here and for that we need to have a state for loading so let's add loading set loading and by default it's going to be false and let's go to our signin button and first let's add a view and inside this view we're going to check if loading is true then we're going to show a loading otherwise we're going to show this touchable opacity so let's just copy this and move this to L Sport and let's indent it now here let's add a view and give this a class name of flex row and justify Center so that our loading State Should display in Center let's close this and here we need to import our loading component that we just created and we need to pause the size so let's use hp8 for the size of our loading animation and let's save this now to be able to see it we need to toggle our loading state so we need to make it true and let's save this okay we can see our load animation uh maybe let's just reduce the size to 6.5 okay that's better so we can display our Lo animation so let's make it false and this will be displayed while signing in when we create this login process so our signin component is complete now we're going to work on our keyboard awarding view but because we don't have a lot of inputs on this screen so we will do it in our sign up screen now we need to copy all of this code because the sign up screen will be very similar so let's copy this into signup screen and we'll just make a few changes starting with the name of this component sign up then this function will be handle register so let's change this and let's reduce the pedding top to S we also going to use a different image for our signup screen so I've already stored it it's called register. PNG so if I save it and go to our sign up page we get an error that's because we change the function name to handle register and we use handle login that's why we're getting this error okay so still a lot to change we need to change this text to sign up so let's find this okay here we need to change this to sign up let's save this and we also don't need need this forgot password as well so we need to remove this container and remove this text as well and let's indent them now let's change that button text to sign up and here at the bottom we see this don't have an account we need to change this as well this should say already have an account have an account then press here there to sign in not sign up and because we changed the text we it needs to go to signin page not sign up so let's change the route name to sign in let's save this now if I press on this button this should go to sign in and if I press on sign up it should move to sign up now here we need to add some more input Fields but before that we need to reduce the size of this image let's use hp2 okay now for our next inputs let's define our references so we're going to use a username reference and a profile reference for the profile URL and let's add them into our condition so that if user does not add that we should alert the user to fill in all the fields and we need to change the alert message to sign up and this will say please fill all the fields and this will begin the register process okay great now let's add the inputs for this username and profile URL let's just copy the email for two times and let's save this now at the top we're going to have a username input so let's just change the placeholder to username and we need to change the email reference to username reference and this profile URL should be at the very last so let's just copy this and place it after the password field and we need to change this to profile URL and let's save this okay now we have all the feeds and we need to change the icons but let's change the reference for the profile as well okay now we need to find the icons for these new inputs so let's go to our Expo icons and first we need to find the icon for username so let's use the icon from feather this is the user icon from feather so let's go to our username field and here instead of octicons we need to import feather icons and the name will be user let's save this and now we have a user icon for the username now for the profile URL we're going to add an image icon so let's search for image and we have an image icon in the feather icons so let's use that let's change the library to feather and the name will be image let's save it now we have all the icons and all the inputs are looking great now next we're going to test if our arrrow message shows if we don't have any data into any field so let's press it and we see this error let's add some data and see if our validation works at gmail.com let's add a password and just random profile URL okay it needs to be a text why is it like a password um we haven't added secure text entry on the image maybe we need to just refresh it so let's just reload the app and go to sign up and test this image URL okay it works so I think it was a cash issue so let's add data again say at gmail.com some random password and a test profile um it shouldn't display this alert because we have all the data um maybe we made a mistake profile password email user us name everything looks all right email password username okay I think we misspelled this this should be current okay let's save this now if I press on this button nothing happens and this means our validations are correct and it's working now the next issue that we're going to fix is our keyboard avoiding view uh you see when I click on a field and open the keyboard This covers the in put and we are not able to type any data into our image field so let's create a custom component to fix this situation let's go to our components and here I'm going to create a file custom keyboard View and let's create a functional component inside this we are going to remove all of this code and we're going to use a component from react native which is keyboard avoiding View and inside this we're going to add a scroll view so that all of our content should be in a scrollable view let's create this and here we need to render the children's because we're going to wrap our sign in and sign up pages with this custom keyboard View and they will be displayed under this scroll view now let's add a behavior property on this keyboard awarding View and this is different for IOS and Android devices but we can check if we are currently on iOS or not using the platform. OS property this will give us an iOS string if we are on iOS device Now using this if we are on iOS the behavior will be padding and if we are on Android devices this will be hide okay now let's add a style for this keyboard avoiding view as Flex one now let's add some properties to our scroll view let's give this a style of Flex one and we're going to make the bounces to false so that when you scroll the counted and it bounces on the edges that shouldn't happen and we need to hide the vertical scroll indicator as well now you can also wrap this in a touchable opacity and uh dismiss the keyboard when you click on it but I found out that it already does that so I don't need to do that now let's go to our signup page and start using this component uh first let's reload the application okay we need to go to our sign up page and here instead of this wrapper let's import our custom keyboard View and let's copy this close tag and replace it here let's save this and now it shouldn't make any change on the signup screen but our keyboard issue should be fixed so let's just just refresh go to sign up now if I click on this nothing will happen but our content is scrollable and we can add data for profile URL or if I directly click on profile URL this will push the inputs so that we can add data for profile URL so this way if you have a lot of inputs on the screen you can use this technique to fix the keyboard avoiding view there might be other solutions to this problem but I found this easy and it works great on IOS and Android devices as well so now we need to implement this on our signin screen as well so let's go to signin component and instead of this view we're going to import custom keyboard View and let's copy this for our closing tag let's save this okay so we don't have the keyboard issue on this screen because we only have two Fields but if we were on a smaller screen then maybe we would have faced this issue so that's why I added the custom keyboard view so now we're going to add fireb authentication and for that we need to go to Firebase console so let's go to our browser and we're going to open console. fire. goole.com and we need to create a new app so let's create a new project and we're going to name our project Firebase chat let's continue um now we don't need Google analytics let's create project okay our project is created let's hit continue and the first thing we're going to do is add a web app so at the top you will see these three icons just click on the web icon and let's name our web app Firebase chat web app uh let's register and we need to install Firebase into our project then we're going to add this configuration for Firebase so let's copy this command to install Firebase let's open our terminal and paste it here okay so now we're going to copy all of this code to our app so let's create a Firebase configuration file into our root directory and paste all of this code here so basically this is initializing our app from Firebase that we can use to connect to our project and use authentication and database so I'm going to create a variable for our authentication Service so we're going to use a function initialize OD initialize o uh maybe we need to import it manually so sometimes it doesn't work you have to import import manually let's import something from Firebase SL now we're going to import another function from O It's called get react native persistence this will be basically used to persist the user from Firebase and we're going to import initialize o as well so let's use initialize o and we're going to pause our application then we're going to add some options for persistence and we're going to use get react native persistence now in this function we're going to add our async storage Library so let's go to our browser and let's search for that Library re native async storage so this is the library that we're going to use so let's just copy this command to quickly install it okay it's installed now let's import this Library async storage from react native uh What's this called yeah this one so let's use this Library into our get re native persistence so this will be responsible for persisting the user into local storage even if you refresh the app we don't lose the user data now let's create another variable for our database and we're going to use a function get fire store and we need to import it manually cuz I'm not sure why Auto Import is not working so we need to import from Firebase slf firestore and we going to import get fire store and let's also import The Collection function for reference of our collection so let's use get fire store and we're going to pause our application now let's create another variable for the reference of our user collection so let's call it users ref and we're going to use a collection function we're going to pause database and the collection name will be users so let's copy this one more time for our rooms collection let's call it room ref I've just added this because later I'm going to add or FES data from these collections so I just added the reference for these two collections so I think this will be all for this file we won't be editing this file again so let's go to Firebase and continue to console and here we're going to enable our authentication so let's click on authentication and hit get started here you will see a bunch of providers but we're going to use a simple one just email and password provider so let's enable it and save it now we also going to enable our fire store to use the database so let's go to Cloud fire store and hit get started so here you will need to choose the location of your Cloud Server uh you can choose this according to whichever the closest region you have so I'm going to choose Singapore and hit next we will be using for test mode and enable Okay so it's setting up okay so we don't see any data because we haven't created any so now let's go to our app and Implement authentication and for that we need to go to our context so if you remember previously this is the use effect hook where we going to decide if the user is authenticated and not so we going to use a hook from Firebase and it's going to return us a call back to unsubscribe it and the hook is called own o State changed I think we need to import it manually so let's import from Firebase SL on o State change now let's use it here so the first parameter will be the authentication variable that we created in our Firebase configuration file and second will be a call back with user value so the way it works is when the user is authenticated we will get the user values otherwise uh user value will be null and we can set the auth tication state to false so if we have the user value we're going to set authenticated as true otherwise we're going to set it as false now based on this we're going to redirect the user to login or sign in so we also need to set the user values because we have the user State as well so if we have the user value we're going to set the user otherwise we're going to set the user as null and lastly we're going to return this unsub call back so that when component and unes this will clear this hook now to test this we're going to implement sign up functionality so let's go to our register function and here we're going to use a function to create user and this will give us a response so let's use await keyword and the function we're going to use is create user with email and password but it's not important so let's import it manually let's import create user with email and password let's also Port sign in with email and password as well because we're going to use it later so now let's use this function and we're going to pass our authentication Service that we created in our Firebase configuration file and we're going to use email and password which will be passed to this function and if we get the response we going to console log to see if we get the user on response so let's just console log response. user if we get the user that will mean user is authenticated and we can update the All State here and we can set the user but I won't recommend it because we are already doing it in all state changed hook so if we sign up and this hook will be triggered automatically we will get the user and we will update the state and the user here so we don't really need to do this so This create user with email and password function creates a user in authentication system but it does not store your username or profile URL so what we need to do is create another collection to store our username and profile and we will use the user U ID as well so let's create a document and to create a document we're going to use add doc method from Firebase so let's import add dog um maybe we need to import it manually let's just import all of the functions that we're going to use in this file from Firebase fire store and we're going to use add dog actually we don't really need it so let's use dog method for a document reference and get dog to get a document and then set dog okay we're not using add dog method because it generates the ID automatically but we're going to set it manually that's why we using set do set document basically creates or updates the existing document but most important it lets us use the manual document ID so that is very useful now for the document reference let's use dog method and inside we're going to pass the DB reference and second will be our collection name which will be users and the third parameter will be the document ID which we will get from our response. user so every user have this U ID which is a unique ID for each user we will use that for each document in the user users collection and after this reference we're going to pass the data for this user so okay we forgot this dot okay all good if you want to learn more about how I'm using all these Firebase function you can visit their documentation I'll leave the link below in the video description so this is how you use a set document method and you can provide your own ID compared to add document so if you go to the documentation for add document you will see we don't have to provide the ID so it automatically creates the ID and adds the data that's why we're using set document I will leave this link into the video description so you can check out now we're going to add our data for our username and the profile URL so let's add that and let's also add the user ID which will be response. user. uid now after this we're going to return a response so let's return an object that will say success true and data will be the user that we just created response. user and if we get any error we will return a response as well but success will be false and we're going to include a message that will be error. message and let's save this okay now this is all done now we're going to go to sign up page and we're going to implement this function so here we have this handled register function first we're going to start the loading as we are signing up and then we're going to use the register function so this will give us a response let's await for register function and for that we need to use our context so let's get our register function from our use Au hook and we're going to use this register function here and inside we're going to pause the email. current value and then we're going to pause the password value then we going to pause the username and the profile URL as well so let's add all the values here and once this is executed we will get the response now we need to set the loading to false and uh let's remove this command and if we get any response we will console log to see uh the result so let's console log this and if we get the success as false on this response that will mean we got an error so we will have a condition for this and we will check if the success value is false we will just alert the user with an error so we will use alert title will be sign up and the message will be the message from response okay let's save this and now we can test this functionality so let's test with invalid data I will use an invalid email so let's use a password and for the profile URL uh let's use test for now and if I hit sign up we see a loading and we get an error inv valid email but this is not user friendly because it says all/ invalid email as you can see in the console and we can't show this to user so we're going to change it so let's go to our Au context and here we're going to store this error do message into a message variable and we're going to check if the message includes this token uh we will check for all/ invalid email so let's just copy this one and if message includes this one then we going to change the message to say only invalid email so that it's more user friendly and now we can send this message instead of this error. message like this and let's save this now let's test this one more time and we will again use an invalid email just to see if we are getting our error message hit sign up and we got our error message okay great now let's try with the real data at gmail.com let's add our password and for the profile URL let me just copy my channel profile let's go to images and let's use this one um let's open it in another window okay so let's use this URL as our profile URL let's paste it here and hit sign up and we got an error DB does not exist okay I think we forgot to import this DB variable from our Firebase configuration so let's import it but we did sign up as you can see we move to our homepage and that's only possible if the authenticated State change so we got the user in here and we set the authenticated State as true and we set the user but because of this DB error we were unable to create this user document in user collection so if we move to Firebase and let's go to authentication and here you can see a user that is authenticated but it won't be there in user collection because of the DB error but now I fix this so we won't see this again so now let's delete this user and we will try this one more time let's delete it now before we try this again on the home screen we're going to add a button to log out the user so let's go to our home component here and uh let's use the log out method from our use Au hook like this and we're going to create a button just to test if our log out is working title will be sign out so let's save this and um Tex strings must be rendered within a text components but we're not doing it so this may be a cach issue so let's refresh okay so now we're going to create a function handle log out which will be called when we press on this button and we're going to call this log out method inside this and we need to make this function async so that we can use the await keyword let's add an onpress method on this button and we will use handle log out method this will take care of the log functionality for now so let's move to sign up and try this one more time me gmail.com let's add my password and I've already copied the image so let's paste the URL and hit sign up okay so we didn't see any Firebase error but this error again text strings must be rendered within a text but we are not doing it not sure why this happening maybe we need to comment this button okay it's gone so we see our home screen that mean our sign up functionality working so let's add a pressable instead of this button and we will use a text component inside this it will say sign out and uh we will add a on press method on this pressable and we will use our handle logout method here okay so our sign up was successful and we can see the logs in the console so we got the user and even if I refresh the app now we will see the home screen again because Firebase is handling all the session data and is storing the user data into the local storage basically every time we refresh the app our on off State change method triggers and we get the user that is authenticated so if I console log this and save this we will see we got the user and that is the user we currently signed up with and here we have the uid at the bottom you can see and we use this ID to create the user document in the users collection so now we can refresh the app and we will see the home screen because the user is authenticated and even if I remove the apps from recent apps and open the IOS app again it will still go to home screen and that's because we used a local storage that Firebase uses to persist the user so if I go to Firebase configuration you can see here we use asnc storage and Firebase uses it to purist the user session so when we refresh the app or open the app this on off State change triggers and we get the user and then we set the authenticated state but after this authentication we also created a document inside users collection so let's go to Firebase and go to fir store database okay so you can see we got a users collection and inside this we got a document with a document ID which will be same as the user U ID for from our authenticated user this will be the same as this ID so inside this we got the profile URL username and the user ID now let's go back and Implement our sign out functionality let's move to log out function and here we need to use a function from Firebase which is sign out we need to import it manually so let's import it from Firebase SL now let's minimize this terminal okay so let's use this sign out method here and if we are signed out we're going to return our response with success as true but if we get any error while signing out we will return success as false and we will return an error message so currently we are getting the user when the user is authenticated but when we press the sign out we will get the user as null and we will hope fully move to signin page so if I open the console you can see we got the user and here we will get the user as null so let's press on this button and it doesn't work so let's move to our home screen and we have applied this method so maybe we need to refresh the app uh let's try this one more time um nothing happens and we don't see any logs maybe we made a mistake Che somewhere let's go to all contacts uh okay so we need to add our all service here that we created in our Firebase config so now when I press on this button we move to sign in and as you can see in the console we got the user as null and this is happening because when we signed out this hook triggered and we got the user as null and because it's null we will set the authenticated State as false and if I go to root layout you can see if the authenticated state is false the router will redirect us to the signin page okay so let's go to sign up and uh now I'm going to try to register the same email that we registered before just to see if the validation from Firebase is working so let's add password some test URL and we got this error o email is already in news but we're not going to show this error so let's copy this and we will change this message let's go to register and let's copy this one and if the message contains this that means we need to change it and let's change this to this email is already in use okay let's save this uh now let's try this one more time with the same email this time we won't get this ugly error so let's sign up and it's working okay so now we need to work on our sign-in functionality so let's go to our login function and here we need to call a function that will give us a response and we already have imported this function sign in with email and password we need to add our authentication Service email and password then we're going to return a response as success true and if you get any error then and we will just copy the error messages from our register function because we're going to use the same structure here and I'm going to remove email already in use because this time we are signing in so we won't get this error now let's go to our signin page and implement this login function so here we need to start the loading first so let's set the loading as true and then we going to get a response from our login function await login and we need to get this login function from our context so let's use our use Au hook and inside this login function we're going to provide our email value and the password value so we are using reference so let's use reference current value and password reference current value okay so let's set the loading to false and here we're going to check if the success value from response is false then we're going to show this error to user so we're going to use alert from react native and the title will be sign in and message will be the message property from our response object okay so let's save this and I'm going to try this with wrong credentials just so that we can add our validations and let's see what type of error we get so we got all invalid credentials but we're not going to show this to user so we didn't console log this and that's why we can't see it so what I'm going to do is uh I'm going to add a console log here to show this response and I'm going to try this one more time sign in and we console log this now I'm going to copy this and we need to change this message into our login function so let's just copy this and if the message includes this then we're going to change this to wrong credentials okay let's save this and try this one last time just to see if we got everything right then hit sign up okay so everything looks fine uh let's go to sign in and before we try with real data everything looks right let's just remove this comment okay now let's try with the user that we registered before @gmail.com and let's choose my password and hit sign in okay so we moving to home screen that means our login functionality is also working and our validations are also correct so let's go to all context and here you will notice in the console we got the user and when we logged in this all state changed hook triggered and we got the user and then we set it into the user state that we can use anywhere but this is not the complete user data and I will show you in a second if I go to home component and here I can use this user data so let's get this user from use o and let me console log this user data so if I save this you will see the user data in the console but this data is coming from authentication Service and it does not include the username and the profile URL that we stored into the user collection so if we move to Firebase we will see we also need the user username and user profile data to show into our application so for that what we will need to do is go to our Au context and here when we get the user uh we need to update the user data so what we will do is we will pass the user U ID and we will fetch the user data based on this ID and then we will update the username and the profile data so let's create this function update user data this will be an asyn function and we will receive the user ID and based on this ID we can fetch the user data because uh if you remember previously we stored the user with the uid so that's why it is very important now let's use the doc method from Firebase to get the reference of this document let's use DB and the user collection and the user ID now based on this reference we can get the document data so we will get a document Snapshot from using a function get dog make sure you import get dog from Firebase not get documents so this will return as a document snapshot and we need to pause the document reference and here we can check if the document exist on this snapshot so we will use exist function to check if the document exists uh make sure this is a function and if this exists then we can get the data from this snapshot using the doc snap. data function Now using this data we can update the user value so let's use the set user method and we're going to provide the user values but this can be null if we refresh the app but let's add it anyways now let's add other values like username and we're going to need a profile URL from the user data and the user ID because our Au user can be null so we're going to use this user ID and this needs to be colon okay so let's save this and we should be getting this updated data after some time so at the bottom you can see uh we got the username as Nomi and we also must be getting the profile URL somewhere and this object has a lot of properties so it's really hard to find any property let's just search for the profile URL and this will be highlighted profile URL okay so we got the profile URL here and this is the image and we got the username as well that we can use into our application so we need to comment some of these console logs because our terminal looks a total mess so we still are getting user data and that is coming from our home component let's comment this out let's refresh the app and this time we won't see anything so let's uncomment this console log so we can see the user data but this data was all user user data that we saw previously but uh as we called the update user data and at that point the user was null so we only seeing the collection data and the user ID so I'm sure this is not confusing so now we have the user data and oh I just noticed we imported the button from react native web web and that's why it wasn't working it was very annoying so let's just remove this now let's log out and try to register some more users let's go to sign up and here let's use Jon Snow jn@ gmail.com and let's ose a password and for the profile let's use this image so let's copy the URL and paste it here and hit sign up and hopefully we don't see any error this time okay so we are signing in and we are moving to home screen now let's see if we can see this user in the fireb console so you can see we have this second document and if we click on this we get the user ID JN snow profile URL so this is all working now let's create one more account so let's go to sign up um let's use Tom Tom gmail.com and this is from our cartoon characters Tom and Jerry so let's use an image let's close this one and we're going to use this image let's copy the URL and paste it here and hit sign up and we are moving to home screen so our sign up is working now let's sign out sign out is working and let's test our sign in one last time let's put our password hit sign in okay so all the functionalities are working and with this we have successfully implemented authentication from Firebase into our application so now we're going to design our home section and we're going to add a custom header for our home screen so before that we need to set a background color of white for our home screen so let's add a CLA of Flex one and background of white um it's not applying let's refresh okay so we can see the background white now we're going to go to our app layout and we are going to change the header for this screen so we need to add this screen to this stag that's use stag do screen and let's add the name property which will be home and we're going to use some options where we can use the header component so in this function we need to add our custom header so let's move to components and create create home header let's create a functional component let's save this and use it here now this is going to replace the header that is provided by the Expo router so let's save this and we have a warning no out named home exist um it's because we used the home with capital age so it needs to be small age okay so we can see the home header at the top now let's go to our header and start designing we also going to need our responsive Library so let's copy it from signin screen to here now let's give this container a pedding top so that the content inside won't conflict with the notch area here we can add a different padding for IOS and Android devices and we will need to make a check if the device is iOS or not using the platform. OS property now we can use this iOS variable to provide different pedding for both the platforms and for the pedding we're going to use the top property from safe area inserts so let's get the top property from a hook called use safe area inserts and for iOS we'll use the top property but for Android we need to increase it by 10 pixels let's save this and our content is safe from the N area so inside this component we're going to add a text component and our user profile so let's make it Flex row and justify between let's also add a little horizontal padding so let's add PX of five and let's add a background of indigo 400 padding bottom of six and we need to make the bottom rounded so let's choose rounded bottom of 3XL and let's save it now we can see our header but let's add a shadow so let's use Shadow class okay it looks good now inside this header component we're going to add a text view so let's add a rapper around it and let's add our text component that will say chats because we're going to show a list of all the chats here now let's make it responsive using the font size of hp3 and let's also add the class names to make it Bard uh let's use Font media and text should be white okay so it looks good now after this view we're going to add the profile image so let's add a view now we can use the image component from react native but it does not use cachier so we going to need something that uses cachier so our images won't have to load again and again so what we're going to use is Expo image so this will only load the image once and then it will show the loaded image so that is very helpful now let's install this using this command let's open the terminal and paste the command here okay so it's installing uh now we need to import it so let's copy this and let's remove this and paste it here it uses a blur hash that is also a blurred image but as a placeholder so this will be shown until the real image loads so we can use this as well so let's copy this image code and paste it here let's indent it okay now let's give this a style with a height of HP 4.3 let's use aspect ratio of one border radius of 100 to make it rounded okay so now we can remove these two proper properties we don't need it actually we do need the transition so let's keep it and transition is the time until the placeholder image shows so let's make it one uh 500 and for the blood hash we are going to store it somewhere so let's create a folder your tails and inside this let's create a file common.js and here we will keep our blur hash so let's copy this line and P paste it here okay so let's do that and Export it from here okay now we can use the blood hash and we can save it so now we can see our profile image and this Blood hash will show for 500 milliseconds and then we'll show the real image now for the image we're going to use the currently logged in user image and that we can get from the user property as profile URL now we need to use the user from our use Au hook because we already stored it into our context so let's use use Au and let's save it okay so we can see the profile image of the currently logged in user so if I log out and log in with a different account it will show the profile image accordingly so let's log in with Jon Snow's account let's hit sign in it's going to load the image for the first time but after that it won't have to load the image so now we're going to add a context menu on top of this image and for that we're going to use a component react native popup menu and here is how it looks uh it doesn't look good but we can work on the design so let's copy this line and install this component into our app let's space it here and it's done now let's see how we can use this so let's go to the documentation and we're going to use this menu provider so let's copy this and we're going to wrap our entire app with this so let's go to root layout and copy this here we are doing this because uh the menu shows on top of all the components so we need to wrap this around our app let's indent it and save it now let's see the menu component okay so we have wrapped around the app now there are a lot of components so menu trigger and options let's just copy all of them and because we're going to use it in our home header let's paste them here and let's indent them we need to indent it like this and uh we need to import all the components as well so let's copy this statement and paste it here now let's save this and see how it looks like okay so we got an option select action on top of the profile picture that selected okay so we got it working but we want to make our profile image as a trigger for this menu so for now let's just comment these menu options and let's add a closing tag for this menu trigger let's remove this text and inside this we will move our profile image like this intent this okay so let's save this now we won't see the text but let's uncomment this to see if it's working and if I click on this okay so our profile image is the trigger for this menu now so if you want to add styles to this menu trigger you can do that as well you just need a property custom Styles and inside this we can add another property uh I believe it's called trigger wrapper and this is an object for all the styles for this wrapper so let's add our comment trigger wrapper style I'm going to leave it as it is but if you want to style it differently you can do that as well now inside the components folder we're going to add another component for custom menu items so we're going to remove the menu options and we will be creating our own so let's create a new file custom menu items and inside this we're going to export a component so let's call it menu item and this is going to receive the text property and action and the value for this action and an icon for this menu item so now we're going to return the menu option component so it's not going to Auto Import so let's go to our header and this is the component so let's copy the import statement let's copy this entire code and paste it here now now let's move all of this we only need the menu option let's move these as well and let's use the menu option here now we're going to use our responsive Library here so let's move to our parent component and copy this responsive Library here okay so now when user presses on this menu option we need to add a property on select and here we can call the action and the value passed to this component like this okay so inside this we will add a view and that will be the view for our menu item so let's give it a padding horizontal of four and padding vertical of four one let's make it Flex row because we're going to add the text and the icon side by side justify between and item center now here we're going to use the text and the icon but let's use the text component for both of them just for testing to see if everything works let's save this okay so now we can use this so let's go to our parent component and we need to remove these menu options so that we can use our custom menu item now let's import it from Custom menu items and let's close it and save it and see uh how it looks so if I click on this we get this error okay so we need to import The View let's also import the text component from RE native as well now let's save this and test this again okay so we can see our custom menu item now here we're going to have two menu items one for for the profile and other for the log out button so let's go to home header and add these icons and the text properties so for the first one we're going to have a text property as profile and we're going to have an action which will be a function handle profile and for the value uh let's just use null for now and for the icon we're going to use the user icon from feather icons we already used this icon into our signup screen so let's use feather icons the name will be user and for the size let's use HP 2.5 and let's add the neutral color for this icon and let's close it and save it okay so this function doesn't exist so let's create this function handle profile let's leave this empty for now and let's save it so the error is gone now if we move to menu item we can use this text and the icon property so let's remove this actually we're going to use the text first so let's remove this and add a text property and let's add a responsive font size of HP 1.7 and let's add a class name to make it board let's use a class font semi board and for the text color let's use neutral 600 and inside this we can use our text property and after this we can use our icon so let's save this and uh now if we click on this we can see our text property and the icon coming from our home header so now we can copy this for our sign out menu item as well and let's change the text to sign out and let's change this function to handle logout and let's create this function we need to make this async because we're going to call an async function inside this and let's await for the log out function and we can use this log out function from our use Au hook it needs to be log out so let's get this function from our use Au hook and let's save this this is going to log us out from the application now we will need a different icon for this sign out button we can't use the user icon let's go to Expo Vector icons and find the log out icon okay we can use this log out icon from and design so let's import the end design icons and we will change the name to log out okay so let's save this and if I click on the menu now we will will see two items but now uh we will need a divider between them so let's create another function let's call it divider and this is going to return a view which will be a very thin line between these two items so let's return a view and give this a class name of pedding let's use pedding of one pixel and you can use the custom paddings like this width will be full and background of neutral 200 and let's save this now we can use this divider between these two items and let's save this and now we can see the divider between these two items now we're going to work on the design of these menu options so let's add a property custom Styles in menu options and inside this we can add another property option container and here we can add all the Styles so let's add border radius of 10 border curve as continuous and to place it anywhere around the component we can add margin top margin left so you can use these values according to wherever you want to place it so I'm going to use margin top as 40 and margin left as minus 30 and let's use the background as white and let's save this okay it looks good and the placement is right so this way you can add styles to your menu options so now we're going to reduce the shadow under this menu option so let's use the shadow opacity as 0.2 and let's add Shadow offset and we will use height and width as zero now I also want to make it a bit smaller so for that we can use the width property so let's use width as 160 and save it okay it looks good now and we have reduced the shadow as well as well now let's see if the sign out works okay it's working and that's because we implemented a log out function inside this that's coming from our context so let's sign it with my other account Nomi gmail.com let show my password and sign in okay everything's working um we need to change the p in the profile that needs to be Capital so let's change this to Capital and let's save it so this way you can add these popup menus inside your app and you can design and place them wherever you want in your application so now we're going to add a user list on the home screen so for that let's go to our home component and uh we're going to have a user list here so let's remove this and let's create a state for storing all the US user and for now I'll just use dummy data so it will be an array with this dummy data so we don't really need this and we're going to use a component status bar here to make all the fonts in our status bar white like this and here we're going to check if we have any users then we will show a user list otherwise we are going to have a container here that will show a loading let's give it a class name of flex and item Center and to add a padding top we will'll just add a Top Value and for that we'll use our height percentage function so let's copy it from our signin screen to this component and we'll use HP of 30 um to get rid of these red lines we going to need to add something if we have the users so so here we will have a chat list component so let's add chat list we're going to pause the users to this component and for the loading uh we will just use a built-in component activity indicator so let's import that we will have a large loading component so let's add size as large okay uh we will need to create this component so let's go to our components folder and create a new component chat list create a function and this will receive the users that we're going to pause from home component let's save this and import it here okay now let's save this and see okay we can see the chat list but to be able to see this loading we need to remove this dummy data okay um why is this small okay so we misspelled this it should be large so this is how the loading will show but you can can use the loading component that we created before using load animations so let me import that and let's give this a size of hp10 and if I save this we can see the loader but you can use either one but I'm going to use the activity indicator here so I'll just use this and uh let's add the values so that we can see our chat list component okay now we already moved the log functionality to header so let's remove this and here we're going to have function get users this will be an async function and here we'll fet the users from firar so let's just add a comment for now and we're going to call this inside use effect Hook when this component mounts so let's call this function here we also going to make a check here to see if we have an authenticated user and we have the user U ID only then we going to make this call so let's add this condition and we will call this get users function for now we will just implement the chat list with dumy data but later we will implement this get users function so now let's go to chat list and start designing let's give this container a class of Flex one so that it has a full space and here we going to use a flat list component to show a list of all the users and the data for this flat list will be the users and let's add the content container style Le one and AED vertical of 25 now let's add a key extractor for now we'll just use a random value so for that we will just add math. random function and we need to hide the vertical scroll bars so let's add vertical scroll indicator to false and for the item let's use render item property and here we will have the item and the index and we will return a component chat item item so let's go to our components and create this component CH item. JS and let's create a functional component and save it now let's import it here and we going to pause the item data so let's have a property item as the item and let's close it now let's close the flat list component and save it to see if we have any errors okay so we can see three items and these are coming from our dummy data so if I go to home you can see we have the dummy data that's why we are seeing three chat items let's also add the index property to chat item in case if we need it now let's go to chat item and here we will receive the item property which will be the user now let's remove this and here we will have a touchable opacity component and inside this we're going to have an image of the user for now we will just use a dummy image from our assets so let's add that into assets images and avatar.png and for the style let's use our HP function to give this a height of HP uh we haven't imported it so let's go to sign in and copy this import statement um let's past it here and let's give this a height of hp6 and an aspect ratio of one and let's close it and save it okay we can see three dummy images and these are coming from our assets as I've already stored all the assets into my assets folder in the images so this is the image that we're currently showing what we'll change this later when we get the actual data from Firebase so don't worry about it let's also add a class name to make this image rounded like this okay so after this image we're going to display the name the last message and the time of the message for that user so let's add a comment now we're going to need to add some classes for the container to make them Flex row so let's add a class name and give this a class of flex row justify between margin horizontal of four and item Center a gap of three and a bottom margin of four and a padding bottom of four now to separate this we are going to add a border bottom so let's give this a color of neutral 200 okay let's save this um it shouldn't look like this but maybe we need to add the name so let's add a container for the name and last message let's make it Flex one and gap of one now here we need to add another container for the name and the time of the message so let's make it Flex row and justify between now first we will add the name of the user so let's add a text component and here we will just say no me for now uh why can't we see it um did we misspell the height no maybe we should remove this and add a of hp6 okay we can see the name I don't know why it wasn't working but it should have worked so now let's give this name a style of responsive font size of HP 1.8 and let's add a class name to make it Bard so let's add font semi bold and for the text color let's use neutral 800 okay looks good now let's copy this one more time for our time of the message so let's use 1.6 for the font size and uh let's make it font medium and for the text color let's use neutral 500 and here we will show time okay so here we will show the time of the message if we have the Lost message now under this row we will add the loss message so let's add a style and give it a font size of HP 1.6 and let's also add a class name to make it bold so let's use Font medium and text neutral of 500 and here we will show the Lost message I'm using Demi data for now but we will replace it once we get the data from Firebase now we can see the list but I don't want to show the Border bottom for the last item so we will need a way to hide this so let's go to chat list component and here here I will create a property no border and in this property we will check if the item is the last item so let's say if index + 1 equals to the total length of the users that means it's the last item so we're not going to show the border for the last item now let's also pause a router from this component because we will need it to navigate to message history and we cannot do this in Chad item because every time Chad item renders it will declare the router so that is not a good practice now let's intend this and go to chat item and here we will receive the no border and the router property now let's use this no border property and we have to convert this to back ticks let's do that here and let's just copy this border bottom class and here we need to use the no border property and if that's true we are going to have have an empty string otherwise we will show the Border bottom so you can see on the last item we don't have the Border bottom and it looks good now we're going to go to home screen and fetch all the users from Firebase so go to home component and here we're going to fetch all the users but before we do that we are going to check the documentation from Firebase to see how we're going to do that I'm showing you this because if you stuck somewhere you can visit their documentation to see all the implementation so we're going to use a snippet like this we are going to use a query function that will receive a reference of the collection and using where function we can apply a condition to any property and here's another example that fetches the cities and if you're curious about the operators here's the list of all the operators that you can use in wear condition so if you have more questions about this I will leave the link of this page into the video description so you can check out okay now let's go to our app and first we are going to need a query so let's create a constant and import the query function and this will receive a reference of the collection so we'll use a users ref we already did this if you remember previously we created this reference into our Firebase configuration so now we're going to use that and here we're going to create a condition using wear function so we need to fetch all the users except the currently logged in user so let's make a condition if the user ID is not equal to to the user ID of the currently logged in user and we can get the U ID of the user and this will fetch us all the users except the currently logged in user so we'll make a query and we will add aware condition where the user U ID is not equal to this and this will fetch us all the users So based on this query we're going to call another function to fetch all the data and the function is get dogs and we need to pass the query to this function let's create a data array to store the documents data and we're going to Loop through the documents in the cury snapshot now this is a bit confusing because for each document data we have to call a data function on each document so let's push all the document data in the data array and we're going to console log this data to see if we actually CAU the data so CAU users as data okay so now let's open our terminal and uh let's refresh our app and we got the users in the console and we hopefully should get two users so uh we got JN snow and we got the other user as Tom so we're getting the users now we can set this user into our state so let's remove this and set users as data and now we can remove the dummy data as well so first it will show the loading and then it will fet the user and show the users for now we have two users but now we need to change the dumy values to real user values so let's go to our chat list component and uh here we need to go to chat item first let's replace the user image so let's remove this tummy image and use the URI as the item. profile URL and let's save this okay we can see the real images of the users now we're not going to use this image component because it doesn't use cache and we're going to remove this and use the image component from Expo image and here we need to add a style for this image so let's just copy the styles from previous image component and uh let's also add a border radius here as well as 100 and let's add a source that will be the item. profile URL now we're going to add a placeholder for this image so until the real images load uh we will show this blur hash that we used before and for the fade in animation time let's use 500 milliseconds and let's close this and save it again we can see the transition so we have added the image now we're going to change the name to the username of the item and let's save this we can see Jon Snow and Tom we're going to leave the time and the last message as it is we will work on that later but now we have a list of users coming from Firebase and it does not include the currently logged in user now when user presses on this chat item it needs to open a message history page so let's have a function open chat room and here we're going to push to another route but we also going to pause the item data because we're going to need it on the chat room page so path name Will be/ chatro and for the parameters we will pass the item so let's save it so this chat room page doesn't exist and if you click on we will get an error so let's go to our app Group and inside this let's create a new file chat room. JS add a functional component and uh let's change the name to Capital chat room let's save this now it should work now let's refresh our app and if we click on the chat item we move to chat room okay now we need to get this data on the chat room that we passed from the chat list component so let's create an item and we can use a hook use local search prams and this will get us the data that we passed from the router so let's console log got item and console the item and save it okay so in the console you can see we got the item data and as we clicked on JN snow so we got his profile user ID and username this is very useful because we can use this data to fetch the message history between the currently logged in user and this user and we can also use this data to display that user in the chat room so that we know who are we talking to in that chat room so now we're going to go into chat room section and we are going to design our header section we are doing this because this current header has a fixed height that's why we need to add a custom header so let's add a class name to our container and give it a full space and a background of white okay now we need to make our fonts in the status bar dark so let's use the component status bar and give this a style of dark now we can see our fonts okay now after this we are going to add our chat room headers component so we haven't created this set so let's go into our components and create a new file chat room header let's create a functional component and save it now let's import it here we will also pause the user to this component that we got from our chat list component so that we can show the user profile and the name on top of the header and we will also post the router so that we will have a back button on this header and we can use the router to go back to previous component so let's use use router and pause the router here okay now similar to how we can change the screen options inside a layout component we can also do that inside the component itself so all we need to do is import the stack. screen component and here I can provide options for this component so let's say if I change the title to empty string and save it you will see our title is gone and we can change it to however we want like let's say chat room and if I save it you will see chat room and if I add a username here we will see the username but I want to keep it as empty because I want to show the username on the left side so now I'm going to add another property header Shadow visible to false this will remove the shadow at the bottom of our header so let's save it and the shadow is gone now I want to add the content on the left side of the header so if I do that it's going to remove the back button as well and the way we can do it is add a header left property this will be a function that will return a temp template so let's give this container a class name of flex row because we will have the back button and the username and the profile so let's have a gap of four now let's add a touchable opacity for our back button and uh for the icon let's go to Expo Vector icons and find an icon let's search for Chevron okay we can use this icon Chevron left from an typo so let's import an typo icons and name will be Chevron left and the size will be um we need to import our responsive Library so let's copy it from sign in and paste it here okay let's give it a size of HP4 and the color will be gray so let me type the hash code for that and save it okay we can see our back icon but it's not working yet so let's add an round press method and we need to get the user and the router properties that we paused from the parent component and using the router we need to call a back function that will hopefully take us back to the previous screen okay so let's save this and test this out okay we're moving back that means it's working now after this button we're going to add another container that will show the user profile and the username so let's give this a class name of flex row item Center and a gap of three and first we will add the image so let's use image component from Expo image and for the source we're going to use the profile URL property from user and remember this user is from the chat list User it's not the currently logged in user so let's add a style and give this a height of HP 4.5 aspect ratio as one and let's add a border radius of 100 to make it rounded now let's save this okay we can see the user profile and if we go back and click on any other user this will show the profile of that user okay it's working now after this image we're going to add the user name as well so let's add a text component and give this a responsive font size of HP 2.5 and let's also have a class name to change the color to neutral 700 and the font to let's say medium and let's use the username property on the user and let's save this now we can see the username as well now our header left is done next we're going to add the header right and we're going to add the video call and the voice call icons here so let's add the property header right now this again will be a function that will return a template so let's return a view with a class name of Flex row and item Center and a gap of eight and inside this view we're going to add icons for call so let's search for call icon and we're going to use the ionicons call icon so let's import the ionicons library and name will be call and the size will be let's say HP 2.8 and let's use the gray color for this icon and let's save this let's see okay we can see the call icon now we're going to copy this one more time and that will be for the video call so let's search for the video so we have a bunch of icons um let's see if we have ionicons okay here you can see uh we have the video cam icon from ionicons we can use this one so let's change the name to video cam and we can see both the icons now I want to add a bar at the bottom of this header uh we could do this with the default header but it wouldn't let us to change the height of the header so that's why we are doing this way now for the bar let's add a view and give this a height of three and let's also add a border bottom and give this a color of neutral 300 and let's save it okay we can see the bar um let's choose the color neutral 200 okay and now it's not very visible to let's change it back to 300 okay now it's good now after this we going to add a view that will contain the message history and our input so let's give it a flex one and justify between a background uh we will have a very subtle neutral background and overflow visible and let's close this now inside this we going to have a container that will show the message history first so let's add a view for that and let's give it a class name of Flex one and here we're going to have a component message list uh we haven't created this component so let's go to components and create this new file message list.js create a functional component let's save it and we need to import put it here and we're going to pause the messages from this component so let's create a state for the messages set messages and initially it will be an empty array now let's pause this messages state to this component and let's save it now we can see our message list component but we'll work on that later now we're going to add a component here that will show the input so let's create another view and give give this a class name of pedding top of two and let's close it now we also going to have some space at the bottom of these components and for that we will use the margin bottom so we will use our responsive library to add margin bottom so let's go to sign in and copy the import statement for this Library paste it here and let's give this margin bottom of HP 1.7 and let's save it now insert this View going to add another view that will be a container for our input and the send icon so let's add a view and give it a class name of flex row and justify between item Center and a margin horizontal of three let's add another view for our input and this will show here because we use justify between for the message list component and this input component so for the input text let's add a view and give this a class name of flex row justify between um let's add a background of white and a border and a padding of two inside this component we're going to add a text input component and for now we'll just add a property placeholder that will say type message and we will close it and save it okay we can see our text component here now we need to change the Border color so let's add a class of Border neutral 300 and let's save it now let's make it rounded as well so let's add a class of rounded full and it's rounded now now we're going to have a padding left from the container to the input so let's add a padding left of five okay great now it's not taking full space and for that we need to add a class name property on the input and let's give it a class name of Flex one and margin right of two because we're going to add an icon on the right side now let's also add a responsive font size of hp2 and save it okay it's looking great now after this text input we're going to add a touchable opacity and that will contain our send icon let's give it a class name to change the background color and to make it rounded let's choose the color neutral 200 and let's also add a padding of two margin right of let's say one pixel and round it full now inside this we're going to add the icon so let's go to our Expo Vector icons and search for the send icon let's see which icon should I use okay here uh we can use the feather icon so let's import feather icons and we're going to use use the icon send so let's name it send and for the size let's use HP of 2.7 and for the color we're going to use the gray color and let's close it and save it okay we can see our input and the icon and I think we should increase the spacing at the bottom so let's use margin bottom of 2.7 it looks good now so next we're going to work on our keyboard awarding View so if I open the keyboard you will see it covers our input and it's not good now let's also see if I type a long string it will fit into the input so let's type this is a test just to see if the text fits perfectly inside this box okay it works great now let's add our keyboard avoiding view um why did I addit this view inner view is also the same so let's just remove this and we will add the margin horizontal to Inner view let's remove this as well and let's add MX of3 and let's indent it now let's save it and it shouldn't make any change not sure why I added this now let's add our custom keyboard view as a rapper around this chat room so let's import our keyboard View View and let's copy this closing tag and paste it here and we need to indent this inner code and let's save it now the UI is not looking good and I know why so we're going to go into custom keyboard View and we're going to add a flex one to the content container style of the scroll view so let's add content container style and add Flex one and save it now the view is looking good but we still have the keyboard issue so if I open it it still covers the input now to fix this we're going to add another property in keyboard awarding View and we will use keyboard vertical offset and this is basically the distance between the top of the screen to the top of the keyboard awarding view it can be different in certain situations but for now I'll use 90 so now if I open the keyboard now our keyboard pushes the input and it looks great now adding these properties has created another issue so if you remember we already used this on our sign up and the signin and if I open the keyboard on those screens now you can see uh we can't really scroll it and the view is not looking good so because we added keyboard vertical offset and the flex one to the container of the scroll view that's why it messed up now we need to make some changes so that these properties only exist when we are in a chat room so uh what is my password I think this one okay so let's go to our chat room and here if I open the keyboard we need to add those properties so let's use a flag and based on that we will add these properties to our keyboard awarding view let's use in chat and this will be a Boolean so let's create configuration for our keyboard wording view as an empty object and let's also create another object for scroll view configuration and we will make a condition here to see if we are in a chat then we will add these properties so let's add a property to keyboard wording view configuration as keyboard vertical offset of 90 and for the scroll view configuration we will add our content container style as Flex one now we will use this so let's remove this and spread out all the properties in Key keyboard avoiding view configuration and let's remove this as well and spread out all the properties inside scroll view configuration okay let's save this and our design got messed up and that's because we are not sending this in chat property so let's go to our chat room and let's add a property in chat as true and this will fix our UI and hopefully our keyboard will be working as well okay let's also see see if the keyboard issue is fixed on the signup screen so if I click on any input and open the keyboard we are still able to scroll through inputs and our keyboard does not cover any input and that's because we never added in chat property on the custom keyboard View for the sign in and the sign up and it's working great so there can be other solutions to fix this keyboard issue but I'm using this way because it's very simple and it fixes the keyboard issue on both the Android and the iOS devices so now we in a chat room but we haven't created this chat room so if I move to Firebase you can see we only have the users collection we don't have the rooms so for that we will just create a use effect hook inside this component and inside this we will call a function that will create a chat room so let's call this function create R if it doesn't exist now let's create this function under this use effect hook create room if it's not exist this will be an Asing function because we are going to call the API and here first we're going to get the room ID now we're going to use the user ID from both of the users and this user is the one uh let's call it the second user because this is from our chat list and we already have the currently logged in user we can get it from our use Au hook so this will be currently logged in user now we're going to use the user ID from both of these users and we're going to create a logic that will create a room ID based on these user IDs and we're going to use this user ID to create a room between these two users so now let's move to our utilities and create this function to get a room ID let's call it get room ID and here we will pause the user ID one and user ID 2 and this will create a logic to combine these two user ID so let's sort them first Let's do an array and put all the IDS in here and use the sort function now we're going to combine these sorted IDs with a dash so let's use join method and we will join them by this Dash and now we get our room ID and we will return it from here here now let me explain why we added this logic so we need to get the same room ID for user one and user 2 and in order to do that let's say the user one has the ABC ID and user two has the XYZ ID and this function will always return ABC dxyz because it will sort them and join them again so no matter if you're logged in as user one or user two you will always get the same room ID and using that room ID you can get the same messages for that person so I'm I'm sure that was not too confusing now let's export this function and use it inside our chat room so we're going to call this function here to get the chat room ID and we're going to pause the user IDs so let's first pause the user ID which is currently logged in and then we will pause the user ID which we clicked on from the chat list now we got the user ID now we're going to set this in our database so let's use the fun function set doc this will create a document inside the rooms collection and let's use the doc method from firas and this will have the DB variable that we created and then the name of the collection which is rooms and then the ID of this document which we already have as room ID and after this reference we're going to pause an object that will contain all the data for this document and we are going to pause the room ID and let's also create a created at property when this room was created and we're going to use a property Tim stamp from Firebase and we're going to call a function from date this will let us create a time stamp from current date and this will hopefully create a document and the collection if it's already not there now let's move back and let's save it and now if I go into any chat room it will hopefully create a chat room for that user and and the currently logged in user now let's go to Firebase and refresh and just wait a bit okay we can see the rooms collection and inside the room collection we already have a document and this document was created when we clicked on Jon's account and you can see the combined user ID as a room ID now moving back we're going to create a state for our message text so instead of State we're going to create a reference for the text because updating the reference won't reender the entire app so let's go to our text input and here create a function on change text and we will set the value with the current value of the text reference now this is very useful because on the performance side it won't render the page again and again if I type any character so that is very useful now next we're going to handle send message functionality so for that we we need to add an onpress method on this button and we will create a function handle send message now let's create this function and this will be an async function because we're going to call the Firebase API and first we're going to get the message from the current value of text reference and we're going to trim it to remove the spaces and if we don't have the message we are going to return from here otherwise we're going to start sending the message so let's add and try catch blog just so if we catch any errors we will just alert the user with the error so this will say message and we will show the error. message here okay now first we're going to get the room ID because we will attach the room ID to each message so we can use the get room ID and we will just pause the currently logged in user ID and the user ID which we clicked on so this will get us the room ID next we're going to add a document reference which will be the reference of the document we created while we open this chat room so to create this we're going to use the dog method we're going to pause DB and the collection name and the ID of the document which is room ID now inside this document we're going to create another collection for the messages so let's create a messages reference and we're going to use the collection function to create a collection and we're going to pause the document reference in which we're going to create this collection and name will be the messages so the way it works is Firebase allows you to create collections inside the documents and we are doing the same thing so we will have the messages collection inside each document in the chat room so we will have the messages collection here for all the messages between these two users now that we have the reference for this collection we can add documents in this messages collection so let's add a new document using add doc method we are using this because we're not concerned with the message ID so Firebase will handle that we will pause the collection reference which is the messages and here we can add the new message data so let's add the user ID who sent this message and let's also add the text for this message which will be the message and let's add the profile URL which we can get from the currently logged in user if you want to show that let's also add the sender name which will be the username of the current user and lastly we're going to add the created add property and let's use the Tim stamp from date to the current date okay so if we create this document we will just console log the ID of this new message so so let's say new message ID is the new document. ID and save this okay so this should all work as expected hopefully now let me briefly explain what we are doing here so first user will type the message and click on the send icon then we will get the document reference of the chat room we are in and inside that document we will have a collection of messages and in that collection we will create a new document which will be the new message and we will console log the message ID so let's try to send the message to John uh let's say hey John and let's send this message okay so we can see a new console log in the terminal and that says new message ID which is this so that means our message was added successfully and to see it we need to go to Firebase and let refresh okay so we can see the message mes collection inside the document and we have one item in that and here we can see all the message data that we passed hey John send her name know me you can add more data to this object by just simply adding more properties here like if user has seen the message or not so there is one issue left which is this message should be cleared when we click on the send icon so for that what we're going to do is create a reference for this input so let's add input refence use ref as null now we're going to use this reference on this input because if we were using the state then it was very easy to clear the message but we're using the reference so we're going to clear the value from the text reference and that won't clear the value from the input so that's why we using input reference and we going to use the clear function on this reference to clear the value inside the input so let's save this and try this one more time let's send a message to Jon Snow and here I'll say how are you and hit send so the message is being cleared and we got the new message ID in the console so now we're going to add a hook that will fetch all the messages from the messages collection inside this room so let's first get the room ID using the get room ID function and we will pass the user ID 1 and user ID 2 which is on the item object and uh now we will create the same reference of the document this is the reference of this chat room object so I'll pause the database rooms collection and the room ID and again we will need to add a reference of the messages collection and we're going to add this hook on this messages collection so that if any update happens in that collection we will get the results now we can only use this message reference as well but I'm going to use a query because we're going to fetch all the documents in an ascending order and do that we going to use the order by function from Firebase so we are posing the messages reference from which we are cing the data and now I'm going to use the order bu which will take the property and the order so we are going to order bu created ad in an ascending order so now we have the query and we're going to use that hook and that hook will return as and call back function to unsubscribe it and hook is called on Snapshot and here we're going to pause the cury and uh it will fetch all the results based on the reference that we using and it will return us as snapshot so the second parameter will be a call back with that snapshot and this will include all the messages as a documents so let's return this function because this needs to be cleared as the component unmounts so in this snapshot call back we going to Loop through all of the documents and we will return the data from all the documents so let's use the map method on the documents and we'll get the data for each document on the data function so we'll return that now we have all the messages so uh let's set them into messages state so now what will happen is every time we make a change to this collection or add any data into this collection this hook will trigger and we'll get all the documents on this snap sh and we'll set them into messages straight and we can use this to display our messages now hopefully this should set all the messages and to see it we are going to console log it here messages like this and let's save it okay so we got a console log in the terminal and here you can see we got all the messages and uh I think we sent two messages so we getting the two messages in an array we got the sender name text T the user ID now we can use this data to display all the messages into the message history component so let's move this console and let's add these messages to our message list component which we're already doing so let's move to message list and receive all the messages here now here we can use a flat list to display all the messages but I've used it before and got an error because uh I was using scroll view inside the keyboard awarding view before so this is kind of a nested situation so we will use scroll View and that will work just fine so let's hide the vertical scroll bars for this component and we will add a padding top using our content container style so let's add a padding top of let's say 10 and inside this we're going to Loop through all of the messages so let's use map method and this will return us a call back with message and the index and here we will return a message item component so we haven't created yet so let's move to our components and add this component message item let's create a functional component and let's save it now here we can import this component and for now we'll just send the message data and let's close it and save it and we can see the two message items that we already sent to Jon Snow so to remove this warning we're going to add the key property as an index on this component now we also going to use the current user data here because based on that we're going to show all the current user messages on the right side so we already have the user property from our go context so let's pause it here as the current user and we will receive it in the message list component and then again we need to pause it on the message item now let's save it and we're going to move to message item and receive these properties we have the message data and the current user now if you remember while adding the message we added the user ID who sent this message now based on that user ID we're going to add a condition so that if the user ID from current user matches the message. user ID that means the current user sent this message so this is my message and we're going to return a view for that to show on the right side so let's add a view and give this a class name of flex row justify end to move to the right side and margin bottom of three and margin right of three as well now let's close it and inside this we're going to add another view to give this container a width of 80% and for that we're going to use our responsive Library so let's import this library from signin component and paste it here so let's use WP of 80 so that this view will have the 80% width and inside this let's add a text component and inside this we're going to add the text property from our message and let's save this okay we can see our two messages that we sent to Jon Snow now these messages needs to be on the right side so let's wrap this text inside another container and let's add a clause for flex and self end to move to the right side and padding of three you also need to make it rounded so let's use rounded 2 XL and background of white and let's close it now let's copy our text component and paste it inside this like this and let's remove this and save it okay we can see our messag is on the right side but why is the padding not working I'm sure it must be some cache issue so now we also going to add the border around these messages so let's add a border class and for the Border color let's use border neutral of 200 let's save it okay we got our padding and the border now let's also add our responsive font size of HP 1.9 okay great now all the messages from my side will show on the right side and if John sends a message they should show on the left side so next we're going to add a template for that so let me log out from my account and we're going to log into John's account let's add a password and hit sign in okay so let's go to Nami and refresh the messages but we can't see it because I'm logged in as JN snow so uh to see the messages let's add an L sport to this if condition and let's just return a text View and we will just simply add message. text to see the messages and we'll see the messages that I sent from my other account to JN snow now you can see the messages now we're going to design it so let's remove it and add a view and this view will have the width of 80% and this will show on the left side so let's give it WP of 80% and let's add a clause name for margin left of three and margin bottom of three as well and inside this let's add another view and let's add a class name of flex and self start to show on the left side wding of three wding horizontal of four and rounded to excel so inside this we going to add the text component that will show our message. text property so we can see our messages on the left side so let's add a background color for the messages let's use Indigo 100 and let's save it great now let's also add a border of indigo 200 um why can't we see it we need to add a border glass as well okay we can see the border now let's also add a responsive font size to this Tex component and let's choose HP of 1.9 and save it okay they're looking great so so now we have added the template for the left and the right side messages so if I type anything in here now uh this will show on the right side so let's say I am good how are you and let's send okay we can see the messages on the left side and what happened is when we sent the messages our hook in the chat room so where is chat room I'm here okay so when we sent the messages our hook got triggered and we got all the messages in the messages collection and we set the messages so that's why we are seeing the new message here so every time we send or receive any message in that chat room this hook will trigger and it will load all the messages for each user so let's comment this and now I'm going to open the Android app so let me just go to console and here if I just type A this will open the app on Android so this is opening on my other screen so let me just drag that simulator here and we need to rebuild so let's press R and this is going to rebuild the app for iOS sorry Android let's make it big until this loads okay we can see our signin component so this is the first time we using this app on Android so let's see if everything works so I'm going to log in with Nomi let's use the password and hit sign in okay it's working great now if I open John snow we got all the messages and the UI is looking great and our keyboard view is working as well now let's type a new message here I'm good and let's send it okay we can see our message here and if I move to iOS we can see the message in there as well let's minimize this iOS simulator and let me just drag that here so that we can test the messaging on both the platforms side by side now on my side let me just ask a question one is the Game of Thrones season 8 coming and let's send it and we will immediately see it on the other side and uh let's just type a reply here from John um let's say I know nothing bro and if I send it we will see it on both sides and all of this is happening through the magic of of this snapshot hook that we use from Firebase so this gets triggered every time we add a document in the messages collection so that's why messages are being updated for both the users and we can see all the messages into the messages collection in this chat room and we can chat with other users and that will create a separate chat room for me and for that user so if I type a new message for Tom hey Tom how are you and that will create a separate chat room for me and Tom and it will put all the messages in that chat room so let me just log out from John's account and I will log in with dom account let me just add a password and hit sign in okay now if I go to noi it will list all the messages between our chat room so that we can see hi Tom how are you now let's return a reply I'm good how are you have you have seen Jerry and let's send we can see it on the other side so let's add some messages from my side I'm good and I haven't seen Jerry okay so our messaging system is working very smoothly and as you can see if I just type the message and click on the send icon it instantly appears on the second user screen and this just one of the ways to implement Firebase messaging into react native I'm sure there must be other ways to have a structure like this but I'm using this way because I found it very easy to understand and if you are a beginner you will find this easy too I hope this is not confusing for you because I tried to explain it in an easy way so now we're going to add the last message and the time of the message and for that we're going to use the same apis that we used for fetching and sending the messages so here is the code and I'll just copy this use effect hook and we're going to paste it inside our home section where we are displaying the chat items so let's go to chat list and inside the chat item let's paste it here and we'll just import all of the things that we used inside this let's import use effect and we don't need this because we won't be creating the room here again let's import get chome ID and for the user we need to have the current user here so let's go to our home section and we need to pause the current user to this chat list user and let's pause the user we already have this from our Au context so it's all good let's save this and let's get this value inside our chat list and we need to pause it to our chat item component as current user we are doing this because we need this current user and the chat item to create the room ID and based on that room we can listen to all the messages inside that room so here instead of user. user ID we'll use current user. user ID and we already passing the item. ID which is a second user and the Order of these IDs does not better because that room ID will always return the same room ID now let's import dog and and the DB variable and this will return a reference of that room using this room ID let's also import The Collection function because this will uh create a reference of the messages collection inside that chat room so for the cury let's import the query function and we already posing the message reference and need to import the order by now for the L message we're going to use the descending order so that we get the last message as the first object so we'll use that now here we're getting all the messages and setting all the messages here but we only need to set the L message here so let's have a state and we'll call it loss message and set loss messages and the default value for this will be undefined and I'll explain why I'm using this so let's put a semicolon and remove this now here we going to check if we have the first item on the L messages that will mean it's a lost message so we'll set that otherwise we're going to set it as null now if it's undefined that means we're still loading the messages and we will show a loading State and if it's null that means we loaded the messages but we couldn't find the messages on Firebase so we can use that to display the loader now let's just console log this lost message to see if we actually getting the messages okay um I think we forgot to import this hook so let's import on Snapshot and let's save it okay we don't see any error and in the console log we can see the Lost message as null okay so first it was undefined because we were loading the messages and then we got the L message now we can use this data to display the L message for each user so let's comment this out first and let's scroll down to see the time and the last message okay so here we need to remove this and let's create a function to render the time and uh for the loss message let's also create another function render loss message now let's create these functions um let's place them here let's create render time and for now we'll just return a string from here time name we'll work on that later now for our L message we will create a function dender lost message and here we will check if the type of the Lost message is undefined that means we are still loading the messages and in that case we're going to return a string that will say loading so let's return loading here and after this we're going to make another check to see if the L message is null or not so let's use if statement if we get the L message will show it otherwise we will return a message like say hi to this user let's use the add Emoji now inside this if statement we will also check if this message was sent by the current user or the second user so let's use current user. user ID if it matches to the L message. user ID that means uh I sent this message and in that case we're going to append a u on this message because this way user can tell by looking at the chat list that I sent this message so after you we'll use the text property from the L message and if I did not send this message I'll just render L message. text okay let's save this and render time does not exist I think we created it okay it should be render time not render item okay we see the loading and then we see the messages but for Jon know says say hi because we haven't sent a message to him so here if I send the message to DOI it will say you send this so let's say okay cool and if I send it and go back here you can see it updates and says you that means we sent this message now let's send a message to Jon Snow and see what happens hey snow um have you seen Jerry now if I send this message this will update the chat list item l message as well so if I go back now it says you sent this message okay it's working now let me minimize this and we will test this on both Android and iOS so if I go to uh Nomi and here I'll just type test and hit enter and now it updates the chat list item instantly and we see the last message and it works from Android side as well so if I go back from this and open this account and let's send a message okay we see another issue here when we open the keyboard it should push all the messages so that we can see the last message but don't worry about it we will fix this later for now let's just send a message from here let's say test two and hit send and we see the message updated on the other side now we also have this keyboard issue on iOS so if I open the keyboard it does not push all the messages and because we're using a scroll view it should scroll down to the last message and we also have one more issue with this keyboard View and we can't see it now but when we have a lot of messages inside a chat room and we try to send a new message it should also scroll down to that new message and by default I don't think it will do that so if I send a new message like say test three and test four you keep sending messages until the messages reach the keyboard view so test six and test s okay so now we can see the problem I was talking about when we send the new message it should scroll down so that we can see this new message by default it's not doing that and if I open the keyboard it should scroll down to see the last message and same thing happens on the Android side if I open this chat room it should scroll down to see the last message and same if I open the keyboard so don't worry about it we have a solution for this and we need to go to our chat room and here if we get the message or we send the message which need to scroll to the end of the scroll View and what we can do is add a reference to this scroll View and using that reference we can scroll to the end of this scroll view so now we're going to do that let's go to chat room and here let's create a reference scroll view reference and use the use ref hook as null and we will pause this reference to this chat list component sorry message list let's pause it here and let's go to this component and we will use the reference to this scroll view now that we have a reference of this component we can scroll to the bottom of this component using a function so let's move to our chat room and here we need to create a function let's create it here let's call it update scroll View and inside this function we're going to use use a set timeout because when we are scrolling down there might be some messages being updated somewhere so we need to add a little DeLay So let's use 100 milliseconds Now using the reference of the scroll view we can call a function to go to the end of the scroll View and the function name is scroll to end and here we're going to pass a property animated as true so that it animates while scrolling down now we can use this function when we are setting the messages here so we can either do that here or we can create another use effect so let's create another use effect and we need to call this function every time our messages gets updated so if we fetch the messages or we send the message this will be called every time and we will scroll down to the bottom now if I save this we will scroll down automatically and that happens when the messages gets updated so if I open the chat room again we scroll to the bottom of the scroll View and that will happen on the Android side as well so if I open the chat from Tom we see it Scrolls down and it has this animated effect but you can turn off this animation by simply setting it to false and now we no longer have this animation effect and if you open a list it will already be at the bottom but I like the scrolling animation so let's make it true but you can set it to false if you don't like the animation so now we have fixed this situation but we haven't fixed this keyboard issue so if we open the keyboard it still does not pushes our messages and for that we need to add a listener on this keyboard so whenever the keyboard is in the view we will again call this function so let's create a constant keyboard did show listener and we need to import the keyboard from react native and add a listener and this event will be keyboard did show so whenever the keyboard is in the view we will again call this function update scroll view so that it Scrolls down to the very end of the scroll view so now we need to remove this keyboard listener as well so let's return a function here this will be called whenever the component unmounts so we need to move the unsub call here as well let's call it here this will remove the on Snapshot hook and we can remove the listener by using remove function like this and let save it okay it's pushing all the messages that's because the keyboard is in the view so if I open the keyboard again it will push all the messages until we see the last message it's not basically pushing all the messages it's scrolling down in the scroll view until we see the last message and that will happen on the Android side as well if you open the chat it will scroll down and if we open the keyboard it will scroll down until we see the last message and now if I send the new message and hit send it will again scroll down to see this last new message and we can see this new message on the other side and we can open and it Scrolls down okay so it's all working great um we forgot to include the time of the message for the L message so let's go to chat room I'm sorry chat item and here we have a function render time and first I'm going to show you what kind of data we're getting for the date of the message so if we have the L message we'll just console log the created ad property so let's say last message time will be L message do created at and let's save it and in the console you can see we got the L message time and it says Nan seconds and the seconds so we need a way to convert this second to a user friendly date so for that I will go to our utilities and here I'll just paste a function that will convert this time so this takes a date and it will get the day and then we'll append a month name so we have all the 12 months here and this will return us in a nice format so we'll show this as the time of the message so let's go back and here first we need to get the date from this last message and that we can get from the created add property now we will return this formate date function and we need to pause a new date and to create this date we need to multiply the seconds with 1,000 because it takes millisecond so let's multiply it by 1,000 now we don't need to return the time string so we can just remove it and let's save it okay we can see the time of the last message 13th January which is the time of recording this video and this will appear on the Android side as well so if we go back to chat items we can see 13th January so hopefully we have covered all the features now let me just minimize this to test them again again side by side let's move them here okay so first we have created this beautiful UI and then we have this context menu which works on both Android and iOS now let's sign out and we have this signin page and sign up page so let's go to sign up and create a new account here we have implemented the keyboard awarding view so uh no matter how many inputs you have this won't conflict with the keyboard view now let's create new user let's say Will Smith and the email will be will gmail.com let's use a password and for the profile URL let's find a profile image we'll just use this one so let's copy the URL and paste it here and hit sign up okay we are logged in and we can see all the users in the app we can't see it here because we haven't added a listener on the users collection but you can do that and this will update the list instantly as we create the user but for now I'll just update the Android app to get this new user okay we got the new user but why does it say the email it should be username I think we mistakenly added the email instead of username so let's just go to Firebase and we will check quickly go to users and yeah I think we we added the email so let's just remove it and just say Will and update it now this won't automatically update here so we need to reload the Android app again okay it's loading and it's fixed so if you haven't sent any message it will say say hi to send the message now let's send a message from will to n me let's say hi and and it instantly updates in the chat list and if you open it we can see the updated message so let's reply from here hey man how are you and if I hit send it will update on both the sides and let's liy from here I'm good and hit set it will update on both sides so this is how the chat system is working and we have made it in a way that it creates a single chat room between the two users and it will keep all the messages in that chat room so we not using a single collection for messages and storing all the user messages in there that is not preferred also we have fetched these users in a way that it doesn't include the currently logged in user so if we open JN know here we have implemented keyboard awarding View and we have made it so that the input stays on top of the keyboard even if we open the keyboard or it's closed and we have implemented the scrolling feature where if you open the keyboard it will scroll down so that we see all the messages so if I open the keyboard you can see it's happening and if I open the keyboard on iOS it Scrolls down so that we see the L messages the only thing we haven't done is this profile view which is in the context menu and I'll leave this up to you guys so you can come up with creative ideas and create a profile view for every logged in user with this our project is complete and we have learned about Firebase authentication we have created this messaging system using fir store and we have created this beautiful UI with Tailwind CSS and Vector icons which is fully responsive by the way also we have fixed a lot of keyboard issues as well if you find this project helpful and you have learned something from this then do like it and share it with your friends if you still have any questions about anything you can ask them into the comment section and I'll try to answer them as soon as possible so see you in the next one
Info
Channel: Code With Nomi
Views: 34,685
Rating: undefined out of 5
Keywords: react native tutorial, react native ui design, react native tutorial for beginners, react native app, react native project, react native crash course, learn react native, react native ui, react vs react native, react native, react native expo, react native for beginners, react native animations, react native vs flutter, react native cli tutorial, react native animation, firebase, realtime chat app react native, firebase authentication, react native chat app, ui, chat app, uiux
Id: wncM96HYcxw
Channel Id: undefined
Length: 183min 44sec (11024 seconds)
Published: Wed Feb 14 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.