Fully Functional Messenger Clone built with Flutter & Firebase 2021

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this video we are going to learn how to build this amazing looking messenger clone so first to give you a quick demo of how this application works is if you as you can see we have a list of users so as i have uh you know send a message to only a single user that's why only a single option is available but if you have send a message to multiple user in that case multiple users will be visible so if i will click on this you can see i have sent a lot of messages to this user now this is how basic a chat application works you will write a message you will click on send and it will be visible to the other user one thing which i have implemented a little bit uh kind of interesting option as well is that while you are writing the message the other person will be able to see that as well so for example if i'm writing this things for the heads whatever the message is you can see the message is uh added already so if the user is on the other phone he or she will be able to see this particular message right and once you will finalize this message then you can send so you can see it's not any update but basically the message was already there so how this helps is basic uh it kind of solves uh one of the problem which i was kind of experiencing recently uh that you know uh one friend of mine was writing a very long message and i was like why the hell you're taking that much time right so that's why uh i think uh you may like this functionality but don't worry if you don't like to have this i'll show you how to get um you know if you don't want to add it it's just a single line of code so it's not going to be too much of your time anyways so as you can see this is the chat application all the messages sent by me will be visible this side all the messages which are sent by the other user will be visible this side in that gray kind of great color code so yeah that's kind of the application and we also have a sign in sign out option functionality so this is the sign out functionality if i click on it i'll be able to sign out of the application if i will click on the sign in with google button i'll be able to sign in with google now as for the name of the application um it's actually uh chat in german that's what i was calling it but i kind of thought you know it's it's too much close looking to messengers so why not just make it a messenger clone right so that's what uh i go with so just a second why is it not signing in okay maybe some internet issue but uh overall i hope you get the point of the demo and we'll make sure to uh build a whole good-looking messenger clone which is something which is which is going to help you learn all of these things so we are implementing the firebase oauth sign in with google site now and sign out functionality we are going to use shared preferences because uh we will be saving the user information locally to the mobile storage then we have this firebase file store option so we will learn how to create update read data from this file store we will also learn how to query the data in file store because basically the chats which we will be showing so for example the list of user you have contacted all of those will be kind of sorted by the last message sent timestamp right so whichever has been sent recently will be at the top uh similarly for the messages which you are sending like in the chat screen all the messages which are visible should be sorted out by timestamp and the message which was sent the last will be visible at the bottom right so all of these very small things will be taken care of and uh if you watch the video till the end i'm sure you are going to learn a lot even if you have built something before to get started with i have created this blank uh or basically new flutter project initially i'm going to start off by getting rid of all the comments so usually what i do is i you know find and i type slash dot star and this is a regress which is going to get rid of all the comments so it's it's bit faster than you know uh individually removing the comments uh also i like to have this pubspec.yaml a little bit cleaner so of course it is useful if you are a newbie to you know kind of see how things works um that is the whole point of the comments but uh but since we are not going to use that that's why i'm going to get rid of it okay so let's save that and i'm going to move back to my main.art file now in this particular file i'll be no i'll i'm not going to use this my home page so i'm going to get rid of it so let let's get rid of that and i'm going to go inside the lib folder and create a new folder called views okay this views folder is going to conclude all the different screen which we are going to have we are going to have a sign in screen so i'm going to create a sign in dot dot we are going to have a home screen which is basically a screen from where we can see the list of all the users we can search for other users by their user name i think i haven't showed that feature yet but don't worry there are so many interesting things about the application which cannot be visible but as i said if you will watch the video till the end i can be sure that you will learn a lot so we have sign in uh screen we have home screen and we have another one which is called the chat stream okay so we have total of three screens in here now let's start by implementing a basic uh bare bone structure of any widget which is going to be importing material and then creating the budget so i'm going to create a stateful widget for sign in because i know i will be showing the sign in loading and stuff so overall i will be updating the state even after uh the widget has been built on the screen right so that's why i'm using a stateful widget in here then the reason for using scaffold is very simple i have this app bar now of course the app bar which we will use we will name that a messenger clone i guess that will be much clearer than this so let me say title title will be a text and that text will be typing it as messenger okay i think that's better okay so that's how it looks like now if i go to my main dot dot you can see it's showing an error because this my home page does not exist anymore so i'm going to go inside the sign in and then to home and i'm going to create a home screen the same board material i'll say stateful widget and call it home okay and for this one i'm just going to copy the same scaffold because i know that the app bar is going to be the same for all of these screen let's do the same for our chat screen so i'll say material oops i think it's not correct um i'll say import material and then i'm going to get rid of the semicolon create a stateful widget call it as chat screen okay i'll save that and this is what we have i'll call it a scaffold and i'll save that so if i go back to my main dot dot now what i will try to do is i'll just show the sign in screen in here okay and since we are not passing any variable down like that so i'll just save that like this okay so bare bone application is created structured so let's just run this application on this device to run the application you just have to click on this bug kind of looking icon uh which shows this debug and run and make sure you have opened a dart file and click on run with dart and flutter if you have any problem running it or any problem down the road like creating this application feel free to comment down in the comment section below most of the cases i'm going to help but if i am not available there are a lot of people who are watching this video so hopefully one another can help as well right so if you feel any problem feel free to comment them down below so let's just wait for a minute or so not minute i i hope few seconds uh to make sure this application is running perfectly fine but before that what we should do is we should go to our spec.eml file over here and i'm going to import all the different dependencies uh or the packages which we are going to use for this okay so rather than uh wasting your time going to each and every individual package i'm going to paste all of them like this so these are the different packages which we are going to use the first package is for firebase authentication so this will be used uh to implement the fireplace oauth then we have firebase code so there has been a recent updates with firebase packages and now you are required to use this firebase code if you want to use any of the firebase functionality then we have this google in so that we can sign in with google i'm going to combine these both so firebase oauth and google sign in so we are going to sign in with google but it is going to be a firebase also that we can you know manage authentication with firebase then we will use shared preferences to save the user information locally we have random string this will be used to generate some ids and this is the cloud file store which is basically firebase file store a lot of updates has been done on cloud file store so if you have watched my last uh series actually which i have created of creating a fully functioning chat application that is the biggest part why i'm creating this video again because a lot of changes has happened in this file store package which are causing a lot of problems for a lot of people right so to continue with now what i will do is i'll first get rid of this debug kind of uh this strip which we have uh let's first save this so when i will save it will automatically start running this flutter packages get or you can click on this button if you are using android studio there will be option right over here to import the packages now what i'm going to do is i'm going to go back to in here i'll say debug and i'll say false that will make sure to get rid of this it does not look good okay so we have a messenger clone in here uh i i don't like the elevation i think but since we are working on android i think we can continue with that that's not a big problem so first of all we will start by implementing that search option so how the search option works is we will have a search uh text field in here there will be an icon you can type the user name and click on the search so if that user with uh if any user existed with that username it will be visible in the list then and you can click on that and send him or her a message okay so let's implement that i'm going to go to my home screen we are right now in the sign in screen right so before continuing to the home screen of search and stuff let's first complete the signing process so sign in process is very simple we basically want to implement the sign in with google functionality so these are the services which for which i'm going to just create another folder i'll call that services folder and that folder is going to have two files the first is going to be oauth dot dot and the second file is going to be database dot dot okay like that if i go inside the dot what i'm going to do is i'm going to create a lot of multiple functions in here usually i go for you know creating the sign up with email sign up with uh sign in with email then we will create the forward password and stuff like that but since we are using sign in with google we will be creating only two functions the first function will be to sign in with google second function to sign out and one function will be there to get the current user so the whole reason why i'm going to create one more function to get the current user is uh because i want to make sure to uh to persist the login state so what do i mean by all of these fancy for persistence word right so the thing is uh if a user signed into my application and he closes he or she closes the application if the application is opened again in that case we want to make sure that the user is pre-logged in we don't want um to show the login screen again and again right so that's why basically what will happen if i have a function to get the current user is in the main.dart i can run that function and check if we have a current user or not if we have a current user i'll send the user directly to the home dot dot which is our home screen but if any case if we don't have the current user then i'll show the sign-in screen okay so i hope everything is clear so far if you feel uh the video is a little bit fast there is an option in youtube where you can decrease the speed of it so i hope that is not a problem but if it is at least do let me know in the comments so i can you know make them better in the for the upcoming videos okay so we are going to first create a class to handle all of these different functions which we are going to create i am going to name this both methods and in here we are going to first uh create a final i'll call it firebase o sorry both like that and then i'll create both is equals to firebase dot instance like that okay and i guess i can just do it like this okay so we have a variable uh which we can use to get the current user which we can use to sign in with firebase o as well and this is uh the one which we are going to use for sign out as well so first i am going to create a function to get the current user okay creating that function is very easy let me just show you how quickly we can do that so we will say get current user this is the name of the function and these are the arguments we are not accepting any argument that's why this is blank and this is the whole function where the function is going to be now inside of this get current user we are going to just say return and then we are going to say code dot current user like that okay then i'm going to move on to create a function to sign in with google so i'll say sign in with google okay inside this function we are going to accept one very important thing which is the build context the reason for accepting the build context is because we will be required to get the context uh if we want to navigate from one screen to another so basically the idea is that once the user is signing with google i want to send the user to the home screen so for doing that we need to get the context if you are not aware of what context is context basically defines the place you are in right now so if you are on the home screen if you are on the sign in screen that is how we can know if we have the context okay so let's move on uh with implementing the sign in with google functionality so first of all we will start by creating a firebase or variable again um if you want you can use this one but i just wanted to keep it separate for this one so let me first say firebase both okay and then i'll say firebase both is equals to is equals to firebase firebase oauth dot instance okay so nothing different this is the same thing which we have done and then i'll say final then i'll create one for google sign in so as i said before we are going to use google sign in but we are going to connect both both of these google sign-in and firebase so that we can uh manage our authenticated user via firebase but we are giving them an option to sign in with google now i'll say new google sign sign in okay so that is basic defining now i want to initiate the sign in with google thing so i'll say google sign in account is equals to google sign in account is equals to google sign in this particular one google sign in dot sign in okay so we created a variable for this and then we are going okay now this will take a time so i'll say await in here uh now if you're not very much aware about a weight and a sink uh i'll highly recommend you two videos which i have done one which is building a wallpaper application and the other one which i did was building a news application from scratch both of them has got really good uh support from the community and uh are really being helped a lot of people to build their application so they can really help you understand this async and await stuff much better but in short you can understand basically uh whenever there is a process which is going to take time to return the value then we use a weight okay our weight is basically specifying that we are that we are not going to continue reading the code below until unless this process is done basically because what happens is if i don't have this await in here we are directly trying to get the value from this right so instantly it is always going to provide a value of none right so that is that is a big problem because if it is always providing a value of null that does not work right so that's the problem that's why we use a weight now if we are using a weight we need to make our function function asynchronous and that's why we use this keyword to make our function asynchronous okay i hope everything is clear so far now let me go ahead and create final google sign in authentication sign in authenticate sorry authentication and then i'll say google sign in authentication is equals to await again the same reason it's going to take some time google sign in account dot authentication okay i hope everything is clear so far now i'll create the oauth credential now what credential is basically we are creating the credential out of that sign in with google option so that with those credentials we can sign in with firebase or so i'll see google booth provider dot credential okay in here i'll say id token so there are two things which we need in there which one will be id token and another one is the access token we can get both of them from the google sign-in authentication we just did google sign-in authentication what is that there we go okay google sign-in authentication dot id token okay and the second thing is access token so i'll say access token and then again i'll say google sign in authentication dot access token okay i hope everything is clear so far now next once we have the credential as i said we are going to sign in with firebase so i'll say firebase oauth dot sign in with credential okay now i can provide these credentials which we got with sign in with google and there we go the firebase authentication is done but what i want to do is once the firebase authentication is done i want to get the user information so what i'll do is i'll create user credential okay this is actually a class with firebase oauth itself it is not something which i created it is something which is in um inside the firebase package itself so then i'll say result or let's just call it user credential nothing special user credential so this is basically going to provide us the result as a user credential let's call it results this is a name okay so that's not a big deal and i'm going to update for this okay so now we have the result result is basically user credential and as you can see i think it's not very clear but uh with result we can get all of these different values so i can say result uh dot user dot you can see i can get all the user's information so that's the whole point of getting the result out of that firebase oauth which we did okay now we have the user details so i'll say user user details is equals to result result dot user so you know kind of rather than calling a result.user dot again and again i'll just created another variable with result.user so this is a user variable so you can we can directly now see user details dot display name email email verified is anonymous and stuff like that okay so we have a lot of these stuff what do we want to do next well i want to first check if we are able to successfully sign in or not okay so how can we test that we can check if result is equal to null or not so i'll say result is equals to equals to null then do nothing if it is not equals to then we want to do something right so i'll say if it is not equals to none okay then only we will continue or else just return okay then i i i don't want to do anything if that so what do we want to do if the result is not equals to null we want to save the user information to our local database then we will upload the user information to our uh firebase file store database because later on we want to implement the search functionality i hope you remember right so to implement the search functionality we have to upload the user information to our database so how are we going to use shared preferences actually using share preferences uh preference is so very easy so let me show you how i exactly do that so i'm going to go inside the lib folder create a new folder called it helper functions inside of that i'm going to create a new file which is going to be called shared preference reference let's just call it share proof helper okay so this is basically shared preferences helper i'm going to rename that to be dot dart extension now again i'm going to create a class called shared preference preference helper now you may be wondering why i'm creating a class for example i did that for this oath as well i am doing that for the shared preferences as well obvious because if we create a class we can directly access all the function inside of it by calling the class and then dot that particular function name right so that's why i usually incorporate all these different functions in a single class so that i can easily access them okay so now what we want to do is we want to create all these different save functions which are going to save the information and get the information so over here we are going to say five information about the user the number one information is user id now what is user id user id is an id generated by firebase for each user who signs in it is a random id so we don't have to kind of generate ourselves for something it will be generated by firebase so i would like to keep a track of that because later on once i am going to upload user information upload the messages create chat rooms we are going to use that uh secondly we will have a user name key so let me also start typing so the first thing i said is user id user id key now you may be wondering why are you creating this keys so just give me a second and i'll show you how why okay so first i'll say static string and what do i need next i want to save the username so as i have already mentioned we will be implementing search by username so we need to have a username right now of course you may already know that a gmail user or a google account user does not all have a username already right so what i am going to do is i am going to get uh the username from the email by removing at the gmail.com from the email so now you know that it is going to be unique all the time it really helps you know we don't have to implement the search to test again and again if the username exists or not stuff like that i hope that all makes sense till now right okay now we are going to move ahead and say string and then we also want to get the display name so display name will be visible a lot like for example when you're chatting with the other user you want to see that and stuff like that i'm going to create a key for this i put i will say user display name key okay so this is basically the key of it and as i said already don't worry i'll tell you why i'm defining the keys already so i'll say uh user email key this is to save the user email so i'll say user email user email key like that and then i'll have a static string user profile key is equals to user profile key now the reason why i have created all of these keys because how shared preferences works is you have to provide the key and then provide the value so if you're saving the value you just have to provide the key and the value if you are getting the value you need the key right so it is kind of a map where we pro uh save our value with the key and we can access our value via key so that's why i'm keeping a track of keys like this because i don't want to misspell any of that because it can really cause problems and i will not be easily able to debug that issue because our code editor will not be able to understand i hope that last thing makes sense why i am creating these separately rather than writing them again and again because as a human i can make mistake and i don't want that to cause problem because once our application scales it it will really become very hard to debug these things which are not exactly able to be tracked by the code editor okay so we are going to create functions to save data so the first first function is going to be to save let's say username username now we need to accept the username of course so i'll say get username and then this is actually just the name of a variable so don't worry about why i used get or something like that this is nothing special this is basically a user uh sorry not a username it's a variable name right i hope that is clear now to use shared preferences we have to first initiate it so i'll say shared perfect no i'll say shared preference says this one and then i'll create a variable like that for that and then await shared preferences and then i'll say dot get instance okay something like that and since we are using await we will have to make our function asynchronous now it's very easy as i said to use a shared preference you just have to say dot and i want to save the value so it is called set so i'll say set string because it is a string of course and here we have to provide the key so what is the key for the username well this is the key for the username what is the value this is the value okay so i hope everything is clear so far now i'm going to return this because this set function is going to return if it is successful or not okay so if it is successful then it will return to if it is not successful then it will return okay so we have a function now to save the username now let's create similar functions to save the display name user email and profile and stuff so i'm not going to create them all again i'm going to copy them so that you know i can save your time but don't worry all the source code is available on github and the link to source code will be in the description so you can get uh grab it from there so all i did is like i have added this you know kind of return type to my functions and uh this is a user email you can see there is no much difference than just changing the key and the value which we are accepting right so that's all what has changed and all of these function are very same i think i have uh spelled it differently before uh okay so this is profile pic okay so basically i'm going to save the user profile picture url so that's what what this is okay so now we have a functions to save the information now let's see how we can create a function to get the information so i'll just say get data now to do that we just create a function called get user name and then i'll go ahead and this line is going to be the same right this is not something which are this is going to be the same and then of course we are using a weight so we need to make our function asynchronous now then i'll say preference dot what do we want to do we want to say get string right because we are getting a string value what is the key of it well key is user name key and there you have it you have provided the key now you have the value now of course we need to return this value so that once we call this function we can use the value which we are getting from it now we can define the written type of it as future string now first of all why am i saying it is a future because it is going to take some time when we get the value from shared preferences it's not as instant processes it is going to take some time now the second reason why i'm using a string is because this is going to return a string so i hope that all makes sense now again same thing i'm not going to create all the functions to get the different user information because they are just the same and i hope it will be much easier for you to just go grab the code i'll um you know what i'll do i'll i'll link my blog link in the first link so that you know you can follow up with the blog and there will be a direct link to the shared preferences helper.dart file in this particular step of implementing shared preferences okay so uh what do we want to do next now we have the shared preferences so now let's move on and save the user information which we are getting from the google sign in so over here i'll go here and i'll say shared preferences helper okay and these brackets and then dot now you can see i can access all the different save and get function so well i want to use the save so i'll just say save user email how can i get the user email i think i have told you that before you can see user details that dot email it's that easy okay so for the next things we are going to say shared preferences helper okay let me just copy this like that dot then i'll say save user id okay so we have saved the email now let's save the id how can we get the id we can say userdetails.uid okay it is called user id which is uid again we will use shared preferences helper dot save now let's save the display name for example so to get the display name you can just say user details dot display name isn't it easy like do let me know if you are finding it interesting so far okay so now we have a save display name uh next we will say is save user profile url okay so this will be used to show the profile picture of the user i don't think i have shown that but uh if you would like to you can so that's why i'm keeping it up if we have enough time i'll obviously try to implement that quick as well so over here i'll say photo url okay so that is how we can get the photo url so now we have saved all the information all we have left to do is upload this information to our firestore database so for that i'm going to open up my chrome browser let me just open it up where is that there we go here is my chrome browser i'm going to move to firebase and i am going to use my the separate account for sample apps there has been too many apps on my gmail like all my limits are exceeded kind of so yeah so you can see i have this is the one which i created last time i'm going to call this messenger clone and we will continue with that i'm not going to use google analytics so let's turn that off create the project it is going to say take few seconds but one question which i have for all of you guys is if you are using mac please let me know in the comment uh because uh i think major of people are just using um windows so that uh in that case we are only going to set up for android um but obviously i have covered to uh you know connect ios application in different applications so if you want to see the uh how we can do that there are different playlists available on the channel but just wanted to get a view of what operating system you are using so just do let me know in the comments what operating system you are using okay so i'm going to go implement the android to implement the android i'll go open the android folder go to the app folder go to the build.gradle and over there i'll i'll just copy this application id okay from here copy that then i'll paste it here then i can click on register app one thing which you can also do you can implement this sha one because it is going to cause a little bit of a problem okay what is it happening okay we will uh because uh what is going to happen is uh when we are implementing the google sign in it is going to cause problem if you don't have a sha 1 key so i'll show you how we can do that so here's my google services json file uh okay we have a lot of them which you might have already expected so i'm going to open up this folder in my explorer explorer is nothing uh but kind of sorry finder yeah finder is basically explorer of windows right so i have to paste that google services file here now this has been renamed because i have a google services json file already in that particular folder where it got downloaded so i am going to remove that one so now you have the google services json file inside the app folder so let's move back and see what we have to do next so now the next step is to click on next we need to add this green line of code to our project level build.gradle file so what do i mean by project level build.gradle file if you go inside the android folder inside app folder we have one build.gradle file and we have one build.gradle file outside the outside one is called project level and this inside one is called app level so i'm going to open up this project level file and i have to paste that green line of code inside this dependencies which is inside the build script okay what is next we have to go inside the app level build.gradle file and we have to add this line so copy that line go to the app uh level build.gradle file and paste it right next we have to copy this implementation which is copied and i'll just paste it here okay so far all of this is done let me save this close this close that save this one as well now as i have mentioned that while we are importing the packages that we are using firebase code right so the reason for using firebase code is we have to first initialize firebase then only we will be able to use any of its services so this is the easiest and the fastest way to initialize a firebase with firebase code so first what we will do is we will save widgets widgets flutter binding dot ensure initialized then i'll say evade firebase firebase okay so i need to make this asynchronous for this i'll say firebase you can see import from firebase score just click enter dot initialize app and just these two lines of code will be more than enough to uh like enough to uh initialize our application uh with firebase so now we have done all of that part what is left well now as i said we will be uploading the data to firestore so let me click on next and continue to the console now to use firestore you have to go to the cloud file store and then we have to click on get started so if we can click on create database we are going to start in production mode but we are going to change this so it does not matter you can use test or production we are going to change this rules anyways okay so i'm going to change the rules first before continuing to anything because a lot of times i do this mistake of you know i i know that uh time of creation that i'll go i will be changing the rules but then i start doing something else and forget about it so i don't want this to happen uh at this time at least so i'll just give it a second few seconds and once this is done then i'll update the rules then only we will continue with any anything else right so okay it's concluded now i'm going to go to the rules over here and this is the rules right now allow read and write if false which basically creates a condition which is always saying no right so it is always saying no to read and write whatever the case so i'm going to change that to always saying yes right and that's that is going to take care of read and write so now even if you are not authenticated you can read and write so what do we want to do next well we have let me close that we have to go to the authentication part because we have to turn google sign in on right because it's not so we have to click on get started okay by the way if you don't know it's a free of course to use firebase just to give you an idea so now i'll enable this one and public facing name is basically you know when someone will click on sign in with google it will show a pop-up and in that pop-up uh google actually have your name there right so i'll just call it messenger messenger and i'll just select the email and then i'll click on save okay okay okay so you can see it is saying about the setup the sha fingerprint so let me quickly show you how we can do that let me just open up a new browser window and i'll say let me just make sure it's visible to you as well so i'll say sha1 key generate so there is a basically this particular one so i i'll add this link in my blog post as i said before all the links will be available in the blog post the blog post link will be in the description so basically we have to copy this for debug mode so initially we are going to implement this for now debug once you are releasing the application then you can use this release mode key so i'm going to copy the debug one go to my uh like project open up the terminal and paste that and hit enter i'm not sure about the secrecy of these like so let me just try to get that sha1 key close that i'm going to go to the users um where should i go next well we are going to go into the project settings and i'm going to add that fingerprint and click on save okay so once that is done let's go back to the authentication and now i'm going to dismiss okay so now i'm going to go ahead and implement the upload of data so how i want the data to be uploaded is if we go to the cloud file store there will be a collection called users inside of that collection we have a user id okay whatever it is and in the user id we will have information like username username we will have uh i don't know we can have user password sorry not password we don't save password in the file store we can save user id of course um we can save user name we can save profile ui so we have four things in here i'm missing something do we are saving email yeah so last will be email so these are the five things which we will save and this is how the structure of our database will look like so now let me show you how you can upload or do this from your application because of course you're not going to open your database for each user right so for this we are going to create some functions and that are going to go inside this database dot add now since we are done with android setup with firebase i'm going to just collapse this particular folder going inside the database fold a file i'll just create a class called database methods database methods and inside of that i'm going to we don't need this because this is only required for functions um inside of that what i'll do is i need to create a function to upload the user information to database so to create that i'm going to create a function called add user info to database okay that is the function name these are the arguments if you want to accept any and over here we will start by saying firebase firestore dot instance so now this is the update uh updated version if you will see my uh last whole playlist on creating a fully functioning chat application with uh flutter and firebase uh this was different right at that point of time we used to use firestore dot instant stuff like that so yeah these are the things which are changed now i can say collection so this is how the like structure of our database is we have a collection collection can have unlimited amount of documents and then documents can have information which are in a map you know key value pairs and there is another collection which we can start inside a document so this is how we structure the data so we want to go inside the user's collection first so i'll specify that here i want to go inside the collection called users and then i want to add a value now there is a reason why i'm saying add there are two ways to update or upload this information first is you can say add second is you can say doc dot send so this id you are looking right over here i have made that to be user id so this is going to be uniquely uh user id for each user it actually helps uh you know while you are doing uh upcoming functions so if you want to update the easier information things like that it will be much easier if you can uh have the document id as the user id so if you want to have this particular id of document something custom or something which you want to provide in that case use this dot doc dot set so in the doc now you can provide the user id but if you use if you want to left that to firebase so for example if you want this to be a random id then you can just say dot add so in that case firebase will generate a random id for you so we will be using this one for this so i need to accept the user id so i'll say string user id now actually we can get the user id in this itself but i'm going to just accept it from the function so we have the user id um so now what i'm going to do is there are two options when it comes to this data now this data is nothing but a map so we can actually create a map here and send it via the function or we can create the map right over here accepting all the values i am actually going to accept the map so i am just going to say map and map is going to have string type data type of keys and dynamic data type of values and this map is nothing but the user info map okay so this is it so this is what i'm going to approach okay now we need to accept this right so i'm going to go ahead in here i'll say database methods again i said i'm creating classes so that i can access the function inside of them via those classes so i'll say add user information i need to provide the user id so i'll copy that i need to provide this user info map so this is how the map will work obviously you know that the data type of the key is going to be string which you can notice here all these keys are string but the data type of this value can be different right so that's why i named that to be dynamic now for the name i'm just going to use the same name for the map and this is how we define a map map is a collection of key value pairs so we need a key so keys can be something like email and what is the email email is this one then we need a username so i'll say username and i i hope it is uh i made that clear how i'm creating the username i'm using the email id and then dot replace all address gmail.com with nothing so this will give me a username now the next thing is i want the display name so i'll just call it a name and i'll say user details user details dot display name display name okay uh the next is going to be image url so i'll say image url profile url which we can get from here okay so this is basically the image url of the profile url url of the user uh this can be used to show the profile picture of the user logged in in the home screen and you know to save it when you are saving or sending the messages and stuff okay so we have this all now what do we want to do next well first of all we want to be notified or get updated when this is done this particular function of add user to database so i'll return this and make this a future and basically i want to wait for this to be done then only i want to continue so i'm going to just make it an asynchronous function so now until unless this is once this is done i want to do something so since i have made this function asynchronous i can go inside here and i can say dot then okay now i can do uh then is basically used to do something up once the you know all the things inside that function is done and this value is not of any use because this is going to you give us the user id which we provided because it actually provides the document id of the document created but since we are the one who is providing the document id so you know that we are going to get this user id in here so we don't want to use that but let's keep it there what i do want to do is i want to send the user to the home screen so let's see how we can do that i'll say navigator dot i will use push replacement here because i want to push that next screen above not just above of it i want to replace the sign-in screen basically this push replacement just to clarify what it means is i'm going to remove the sign-in screen with my home screen so the user will not be able to click on the back button and go back to the sign in screen okay if i have any intention that i want to keep the next screen above of it so that you know user can click on the back button and he or she will be able to come back to the last screen then in that case i would have used only push now for the material for the root we are going to use the material root this is nothing but basically the animation which is going to be happening so it is material page okay so this is basically the animation which kind of happens when we move from one screen to another i'll provide the context because that defines where i am right now and then i'll say arrow that i want to go here so i want to go to the home so i'll just say like that and i'll rem i'll import the home by clicking on that and then just save it so once all of that is saved let me just restart the application of course there's going to be no changes we do have created the function but we haven't uh kind of used them anywhere right so i'm going to go inside the sign in screen create a body section create center widget now center widget is used to align items in center i hope that kind of makes sense so we will have a container here uh why am i creating container container is actually going to be a custom button for sign in with google option so i'll say text and the text says sign in with google let me just quickly grab the color code color hex code which i used for google sign-in which is this so i hope you know the hex code is like six digit code for any color you just yeah so now to provide the color to this container we can just say color color now i am using a hex code color right so i have to do it like this 0xff and like that okay if you wanted you uh to use some of the predefined color then you can say colors dot you know amber or something like that so you can see we have that red color but we want to customize it quite a lot so as a padding edge and set start symmetrical symmetrical horizontal around 16 and vertical around 8. okay i think the font size should i should be a little bit large so i'll say text style font size i'll go ahead fit 16. i want a little bit of a border radius which i really like so i'm going to remove the color now you may be wondering wait a second what is the relation why did you remove the color because whenever we are using our radius we will use the box decoration and if you are using box decoration you cannot define the color outside now i'll say border radius border radius dot circular and that is going to be around 24 so this is how i want this to look like i also want to provide it a bit of a color so i'll say color colors dot white so this is the sign in with google button so what i want is whenever someone will click on it so i want to implement a on click functionality to a widget there are two ways to do that you can either use ink rail or you can use a gesture so let's continue with gesture detector over here and uh in the next someone i'll i'll show you how to use ink value as well over here i want to [Music] call this particular function which is sign in with google to call that i'll say both methods sign in with google and provide the context and the rest of it will be taken care by this function itself so anything else i would like to do let's see let me reload that we have added the sha 1 key so let's finger crossed hope this works let me just reload this click on sign in with google if it worked which it does not seems to be let me just close everything and restart the application again in the meantime if you are at the same place good job click that like button you have watched a lot without clicking that so yeah click that like button it really helps to understand uh you are enjoying the video uh and if you're not at the same pace you are somewhere behind uh please feel free to let me know in the comments where you are stuck and uh yeah we want to make sure that you know you are you can complete the whole video and are completed this application because if you have watched till now don't just go because you have invested some time let's just complete this application it is going to be helpful for you okay so some problem occurred i think it can be a multi-decks issue because we have added cloud file store let me go to the debug console okay what is the error okay so multi-lex issue you can see cannot exceed 64. whenever you see this it is a multitext issue how to solve that it's actually very easy um let me just yeah one thing which you should know about me i do google a lot but i don't so yeah this is the one which we are going to implement we have to implement the multitech support so the first thing which we will do is we will go to this android and we will click on this build.gradle i'll close that paste it here you can remember this as well multitext enabled true but this is the line which is uh the next which is implementation i'm just a bit lazy to learn this i i usually just you know google that and google is good enough to save that for me at the top so anyhow we have to just implement these two lines whenever you are using a cloud firestore okay so make sure to remember this whenever you are using cloud file store just uh implement this multi-links i i usually suggest this on every video and myself forget about it right that's not right i should do something but anyhow um usually i face the problem and then i fix it so it's not that big of a problem but yeah of course it can be helpful if not have to so let's just give it a few seconds and the application is going to run again in the meantime one thing which we can implement is the persistence thing so whenever if a user is signed in and we have sent the user to the home screen if he or she closes the application and opens it again we want to show the home screen because or it's already signed it to implement that we have to go to the main.dart file and over there we will be implementing a future builder function so let's first give this sign in with google a try if it works good if it does not then we have to choose uh something separate or like fix it okay so it's saying i don't know what is it saying fail to load we are in the home so you know how is it said like uh all is well at the end as well right so i hope that it's fine so now let's move on to the uh future builder so what am i doing what is this future builder so let me clear the idea first what we are trying to implement we want to make sure that the user state is persistent which means if he or she have logged in once if he or she closes the application the user don't have to sign in or log in again right to do that what i will use is i will use a future video how future user future builder works is we will be providing it two thing first is future and the second is builder wow how how imaginative is that right so we will provide future and the second is going to be the builder so future will accept a function which is going to take some time so i have actually created a function exactly for this purpose which is going to be dot get current user we are getting the current user it is going to take some time but once we have the correct user we can use that in this builder so i can go say context what is context context defined where i am second we have async snapshot which is basically the data which we got you know from this this future function which is a snapshot like that now inside of that i can say if the snapshot dot has data which means if we get any data from this current user which means we are logged in in that case i want to return home i want to show the home screen if we are not logged in and we are not returning any data uh in that case we want to show the sign-ins we will be required to import home in here and if i'll save that you can see it's like this okay we are seeing that user is not a type of type of dynamic so i think we can make it a user or maybe we can get rid of it okay i think i know what the problem is we need to specify uh the return type of it uh which is going to be the um maybe not just a second if i go back to the main dot dot if i just remove the dynamic with user whatever i'm using is saying the type user is not a subtype of future user if i go in here if i use a weight in asynchronous will that fix it yes it does so that was the problem but anyhow um we are in the home screen now and let me just show you at least so if i'll close the application and i'm going to run the application again i am expecting to see the home screen not the sign in screen so let's see that uh in the in the meantime what i'm going to do is i'm going to implement the sign out functionality so i'll go in inside this sign in screen i'll go at the top or over here sorry in the home screen actually uh i'll go and i want that to be you know kind of the corner option to implement that kind of corner option that app bar we use something called actions and we will have an icon and i'm using a material icon so i can use it like icons dot i want to use something called exit to app and if i'll save that you can see this is the home screen and we are able to see that instantly so yeah thumbs up on the last thing which we did and we have this sign out option i'm going to wrap this with a container which is going to have a little bit of a padding at the both side edge inserts dot symmetrical horizontal around 16 just to you know make it a little bit space um i want to implement a on click so i'll wrap it with a widget we used in inkwell or i think gesture detector last time so this time let's use ink so i'll say on tap and what do i want to do on tab i want to call that sign out function which i have defined in both methods so i'll say both methods and then i'll say sign out dot sign sorry what was the name of that function again okay i haven't implemented it okay so let me just go to the next line and implement that sign out function quick so it's it's a very easy function you just have to say this you just go in here okay sign out because it's going to use a weight first signing out is so easy as oath dot sign out sign out as easy as that what is oath what is something which we define in here but when we are signing the user out we also want to make sure we remove all the information from the shared preferences now you know to use the shared preferences we have this one line kind of patented like you have to use it right so we use this we defined a very uh variable for that and then we will say prefs dot clear this will clear all the information saved um in the shared preferences by our application so i can now save that we have an error in the home so what is that okay now we can use the sign out function dot sign out now if i'll save that and if i click on this sign out i think we are signed out because if i will save this you can see i'm over here but i was not redirected so what i am going to do is when we are sign out i will say dot then if i want to use the dot then i need to wait for the sign up so i'll go in here and what i want to do then let me say dot then i want to go to the sign-in screen push replacement again uh material is brow builder context and you want to go to the sign list and now i'm going to import the sign in screen are we yeah we are in the home so if i'll save that let me click on sign in with google again now of course we have already selected a google account so it will not even show me an option it will just instantly sign me up with google and we have the sign out option if i'll click on that it should uh sign me out and show me the sign in the screen for some reason i guess this then is not working as expected i don't know why just a second okay let me make this a future and if i'll save that now click on this again okay i need to get rid of that i'll click on this you can see i'm redirected here i can click on sign in with google and i can click on this again to sign up so everything is working perfectly as it should so what is the next step next step is to implement the search user with the username we will be able to search the user and then click on it and send him or her a message and say hello how are you so um let's continue doing that so first thing first i'm going to close this go to the home dot dot and over here i'll go create a body section so i'll say body over here we will have a container container container will have a child and that child is going to be a column what is a column then column is used to align widgets vertically so the first thing i want is a row now what is the row row is used to align widgets horizontally so what are the widgets i want to align horizontally is first is the text field what is a text field text is kind of an input box right and we need a icon icon is basically going to be the search icon so whenever you're using text field inside of row make sure to wrap the text field inside expanded widget so you can see we have a text field this is the what is text field and this is the icon now in the text field i want to give a bit of a decoration decoration is nothing but i don't like the border line i don't want the border line and i don't i want a hint text so for that we will use something called decoration and specifically input decoration inside input decoration we can mention border input border dot num okay then i can mention that uh so you can see that border line is gone i want just a hint text so i said text so hint text will be a user name so now you can see user name is visible of course this you know kind of blank look does not look good so i'm going to have it something like a messenger so let me show you how messenger looks like sorry not maps not news where's the images yeah there we go not this one maybe where is the image okay this is the image so you can see we uh we have this kind of search right a little bit of a border we have the search search for people so that is what we are going to implement so i'm going to create something like that let's go in the row i'm going to wrap my row with the container why am i doing that because container have these properties of that you know you can use decoration box decoration and then you can have border you can have border radius you can have color and stuff like that so that's what i want i'll say border and border will have all these properties i want both border from all side first so all will have these properties of color width and style so i will say color will be colors.black which is a material color which we already have available with a flutter we don't have to provide any specific hex code then the next thing which it was asking for was a width so which is going to be one and that's what i am going to keep and the next thing is going to be the style so i do want the style to be kind of solid which means you know it's um border style to be solid so i'll say border style dot solid solid just again border style dot solid and i'm going to see what's the problem is so it is saying too many positional arguments so i think i have specified or pro okay i know what's the problem i need to first say style then provide the water solid correct so now you can see this is how it looks like of course this is not what we want so i'm going to go inside in here and you know rather than providing a margin to this i'll say margin edge instead start symmetric so basically i want a little bit of a you know horizontal space from the side and this side so i'll say horizontal 16 i think 24 will be better not 124 24 is fine so yeah a little bit of space i think 16 is fine what's happening yeah i think 20 is fine whatever value you feel comfortable like so now i want a little bit of a space from the top so what i'll do for that is i'll say margin edge inserts dot um only because i just want it from the top so i'll say from top i want you know what i may need it for bottom as well so i'll just make it symmetric and make it vertical how much i want from vertical let's say around 16 1 6 okay so now i i want a little bit of a border radius this sharp edges does not look good so i'm going to go where am i going to go over here and just after this i'll say border radius and border radius is going to be circular around 8. if i'll save that no 8 does not look good i'll go with 24 now this is what i want now i don't know for what reason but this border looks a little bit thin too thin to me i'm going to make it a little bit of a solid i don't know why it is happening like this um you know what i'm going to make this great yeah i think that looks much better uh we can always increase this because i think it should be but 24 is i guess something good enough i would require a little bit of a padding in here as well because it looks too close the hint text you can see i want it from all the sides around eight maybe no it does not look good from all the sides so i'll just use it for the horizontal one so i'll use the symmetric first and then i'll use the horizontal and i think 16 will be good enough for that looks good so far right now i can type in a username and i can search for it now to search we have to implement a query which is going to be run whenever we will click on that but before we do that here is one thing which you need to understand this is a screen a single screen which is going to have both the option the first option is to search the second option is to see all the users we have already interacted with by interaction i mean like the chatting so if you have already chatted with some users that list should be visible right over here so what i want to do is initially the list of the people we have contacted will be visible but once you will type something in here and click on this that list will be hidden and a list of users by that search will be visible at that time i also want to show a back button in here so that if user want to go back see the list of people he have contacted just click on that back button that is how actually it works in a messenger as well so how can we do that well first let's create a boolean value to keep a track of that so i'll say boolean is searching is equals to false so initially we are not showing that i'll go just before this container row i'll wrap it inside a row because i want that icon to be side of it so i'll say icon icons dot back it's actually arrow back this one and if you are using that you have to expanded this so it was not visible instantly so what i did is i just click on this restart option and it is now visible so what do we want to do next is we want to have a little bit of a space between this arrow and this search option so to create a horizontal space we can use sized box with a width of weight of around 8 okay and if i'll save that you can see we have a space if you want to increase that you can always feel free to increase this value i think 12 will be good yeah so this is there now i want this icon and this size box to be visible only and only if we are searching right when we have typed something and we have clicked on the search so rather than handling the them separately i'll just provide my icon a padding so i'll say padding and i will provide the padding from just one side i'll say padding from edge inserts dot uh only i want that from the right side so i'll say right around 12 right so you can do it like this so the reason why i'm not using size box in this because now i have a single widget to handle um for when to be shown and when not to be right so when we are searching when this is true when we are searching then i would like to show this or else i'll i would like to show a container so what will happen now is you can see it's not visible because we are not searching right now but we will make this searching to be true whenever we will click on this search icon so i'll go into the search icon over here we have yeah so i'll wrap it with a widget i'll call it a gesture detector and i hope like both of the things are clear now you gesture detector and inkwell they are very similar and i am trying to use them like both so that you can learn about both of them so now i'm going to say uh is searching to true now you will be like says wait wait wait wait you also make this what is called set state what is that well this is a set state it is used to update the user interface with the latest information available so since i'm updating this value um i want this user interface to be recreated with the latest information so when uh to do that we call this set state okay you can do it after this as well like are sorry like this um like that okay so all of the things once they are done you can call this set state and the user interface will be updated accordingly so for example if i'll click on this now you can see uh this is searching is has turned to true because it has turned to true whenever when it was creating this whole screen again it is now showing this now what i will do is i will implement a click on this one as well just detected on tap so what will happen is uh i will make this false false if you will click on this back button and at the same time i will clear this text field as well okay so right now we are not keeping a track of this text field so let let me show you that first to keep a track uh of what the user is writing in attack our track or text field we will create something called text editing controller editing editing control so we can name it text editing controller but it is actually a search search user name editing controller and then i'll say is equals to text editing controller okay like that then what i'll do is i'll provide this to my text field how can we do that we can just say controller and then provide that now i can control the text in this text field via that controller so i can say con controller.text is equals to plan okay so now of course as i said before we need to update the set state so that the user interface adapt uh is updated according to the latest information which is saying that is searching is false which means this will not be visible anymore so let's give it a try i'll click on this and you can see it's not visible anymore i click on this it is visible i click on this it is not visible okay so i want to do something when there is something written in this so i want to search for that particular so for example if i write essence card i want to search for that user right so first let's see if our uh is user info is uploading per uh perfectly so you can see this i am since karthivari user has been created with the email which i have logged in with right so what i will do now is i'll remove this because i want to login again and google will login me to the same account so i will install this application first so where is the messenger clone i hope this is the one so i'll install this application and then what i'll do i'll go ahead over here and click on run again now the next step is going to be that i am going to login with another email and then search for this user called i am sanskar and the whole purpose is going to be implementing search so that we can search for a user by username and get all of his information once we have all of the information available we can create a chat room with that user and we can chat with him or her right so let's give it a second and i'll be right okay so the application is running successfully now as i said the next part is to sign in with another gmail account another than this i am says kardawari so i'll just use the indian app guy one and once we are sign in we will be searching for this user with this i am since khadivari username so how can we do that well i'll just go in here i'll type i am so scared there we go so what do i want to do is i want to do is i whenever the user will click on the search icon i want to make a query in my file store database that i want to get a user whose username is equals to this so let me show you how we can actually write a query so we will first go inside the database dot dot let me you know get rid of all the other files which we don't want to use so i'll say close others and no not closer there is we was using home but anyhow i'll go inside the database and i'll make a query so how this query is going to work let me clear this again we are going to search user by username so what let's just call this function get user by username it will accept the username first of course we will need the username to search for the user by username uh and it will work like this we will say firebase file store dot instance this is how all the queries or you know kind of set get thing is going to work firebase file store dot instance this basically helps us go to the main over here this particular dashboard right so then we can you know start going in from this side i can say i want to go inside this collection or maybe another collection and then we can go inside the document so on so forth this is basically kind of the starting point of our firebase firestore database now once we are inside of that where do i want to go well i want to go inside the user's collection so i'll say users and inside of that i'll say where we have to provide the field so i want to track this particular field so i am inside users and where i want to check this username where this username um username is equal to so you can see we have a lot of options in here right so i'll say it is equals to the one which we have received here okay i hope everything is clear so far and i'll say dot snapshots so i can have the latest data by any means so anyhow so now we have this this is going to return a stream you can actually use you know dogs as well but i have done it with steam so i don't want to change something in the middle of it in the middle of the video because i have done that before and it actually sometimes you know kind of take more time for others so i don't want to do that for you guys but don't worry if you are facing any problem again feel free to comment it down below i'm here to help you guys so now this is i specified the written type of the function that it is going to be a future and future of stream query snapshot how do i know that well i saw the this and i know that it is a stream of query snapshot and this is going to take some time so it is a future so i'm going to make it return a weight and i'll make it asynchronous function like that i don't need a weight i guess but yeah okay so now we are returning it like this any questions so far feel free to comment them down okay so now how can i call this function well i'll just go in here to this icon and we already have implemented the gesture detector i don't want this to work if we have nothing written so for example if this is blank then i don't want this to work how can you know if it is blank or not i can say if then i can use the controller which is called search uh search input controller search username editing controller.text i can say is not equals to blank okay then only i'll do this which is this process where it is gone man this right uh let me just get rid of the side one okay so i'm saying is searching true and set a state to like this now i don't want to do just that i actually want to search for the user so in that case i will need to use the database methods and which method exactly i want to use the get username method so i need to provide the username which we can get through the through it like that now one thing which is very important right over here is i don't want to just get information like this i am going to create a separate function in here because i am going to do multiple things on this click so i will say on search button click this is a function name by the way and i'm going to do this here now this is actually returning a future stream of query snapshot so it's actually returning a stream so i'll say stream and i'll call this user's stream now this stream will be saved like that now this is a future so i'll say await and if i'm using a weight i need to make my function asynchronous correct house so now we will just cut that out remove that and i'll just call that function called um on what is it called search button click and just use the semicolon that's all okay so now i will be doing this is searching you know what i'll do this once we i think it's fine to do it here now i'm getting the user uh user's stream now with this user stream i would like to create a list of users so i'll create a widget now this is an interesting widget if you haven't created a widget like this uh so basically by creating it like kind of a function think of it like that you define a name of the function but the written type is a widget right so what is the name of this widget i'm going to name this user search users list list okay so this is going to return our stream builder because we have a stream and through that we are going to create a list so i'm going to say stream builder stream builder will first accept a stream so stream is this user stream and then we will have a builder so i'll say builder and builder will have a context and the snapshot which is nothing but the data which is this uh which we got from this stream by this builder we will be returning return return a list view list view dot build inside that list view builder what i'm going to do is just a second inside that list view builder two things are very important in this item count and item builder so i'll say item count how can i get the item count well first of all i know this is the data which you are getting then in the snapshot uh we will say dot data dot dot q mens dot link so basically we got the data from the snapshot and then we set documents because it is a query and making a query inside of a collection returns multiple documents right now of course it is a reason for this particular query we know that a single document is going to uh you know kind of verify or follow this particular query in that case we are just receiving one doc we are going to receive only one document but that's how this uh query works so we will be kind of expecting multiple documents so that's why we will go inside the snapshot we will say snapshot.data which is the data which we received from it which was a query snapshot and from that query snapshot we set data dot documents we got all the documents and then i said what is the length of it now the second thing is we want the item builder so i'll say item builder item builder always have this context and index now i'll just say return return okay and i'll just show a simple let's say what should we show let's uh let's start by showing the profile image you want okay so rather than text i'm going to say image dot network because we are using the url and how can we get this particular one well we will create a document snapshot wait what is document snapshot well this was the snapshot of the whole data now for individual document we can get the snapshot now you will be like how can we get that well let's call it document snapshot first of all specifically for this particular index and to get the document at this particular index we can just say snapshot dot data dot documents and then provide the index it's that easy now once we have the document snapshot you can just think of it it is a document snapshot so what is the exact data that a document contains well you guessed it right it is a map what is a map map is a collection of key value pairs so how can we get a value of a key inside from a map we can just say uh say the name of the map and then we can provide the key so i want to get the image ui so i'll say image ui like that now if i receive that let's go back and see if that works so i'm going to hot restart and i'm going to click on this so once i clicked on it um what would had happened so of course it is inside of this particular on button search click the user stream was able to get the value but i think we need to call this set state again once you know this is done so what i will do is i will say uh set state after this okay we are not showing this list anywhere that is also a problem where should i show this well i would like to show it just below this particular row right so i'll just go inside the row and i'll say comma first of all and then i'll show this particular list if i'll save that okay it says class query snapshot has no instance of documents receiver null or whatever so okay so what i'm going to do is i need to first make sure we have some data here so to know if this snapshot has any data or not you can just say dot has data if it has data then i'll show the list view builder if it does not have data then i'll show a center child circular progress indicator like that now i'm going to restart the application and here i'm going to search for i am since cut now i don't want to show this particular a search user list if we are not searching so let me implement that quick uh so what do i want to show when we are not searching i would like to show a widget which is actually chat rooms list this chat room is basically a chat room created with uh between two multiple users so i'll just say in here is searching if the user is searching then we will show the search users list if it he or she is not searching then i'll show the chat rooms list chatrooms list so now it is saying column children must not contain any null values but okay so this is actually returning nothing so let me just return container at least okay if i'll add a semicolon okay so now i can type i am says and if i will click on the search it says class query snapshot has no instance getted documents blah blah blah blah blah let's fix this right uh so what am i doing wrong first thing first whenever you are using a widget of list view inside a column because you can see at the end of the day this is a column where we go where it is where it is this one and this particular widget of list is side is is inside of that column so make sure to use string crap once we have shrink wrap now let's move on to this problem so it is saying that no such method error dot q m e n t s so let me make sure i have spelled that correct documents documents okay okay that seems to be correct um and what about this one so like for example this document item builder so documents dot length that is correct and if we talk about document snapshot we have data dot documents then we provided the index it looks right to me i don't know what can be the problem saying instance of query snapshot getter is uh so it is saying getter documents which mean we are saying dot something somewhere right um okay so just for the context we are getting this value am i saving that let me just click on save again okay we are getting that value am i returning it that is a big question yeah i'm returning that okay we are getting that by username we are typing users we are searching for inside the collections of users which is correct correct correct you can get rid of this user id it was assembled document anyways um we have the science installer anything i'm writing the username correct is equals to right um okay let me go back to the error again so it is mentioning that no such method error class query snapshot where is the query snapshot again okay has no instance getter documents so i think somewhere this is the problem so let me check in the debug console which particular line is causing the problem so it is saying 72 lines so let me check what the line is doing column okay columns causing the problem not sure if that is right because sometimes basically okay so it's saying line 28 a level uh widget causing error was this a stream builder so the stream builder is causing the error right class query snapshot query snapshot has no instance of talking okay so let me just fix this first i'll go here and say documents dot length i'll save that okay again same problem if i'll comment this down let's say i just mentioned that to be one it's still a problem so that proves that the problem is not here um let's see if i just grab this all and paste it here where is the problem again let's search for the user and search for it again okay so it says we have a problem and we have the problem in the line 28. so the line kind of doesn't change okay so it's in the stream builder okay it doesn't look like the problem was there so let me just comment back okay so it is saying it is inside the stream builder for some reason okay let me just make sure to confirm everything if it is fine not we have a user's stream how are we updating that user stream we are seeing is equals to database methods dot get user by username once we have that we are updating the state uh so basically we are updating um so once updated then only we will have something in here then we can you know kind of show that but i think the problem which we are facing is that no such query method so i would not like to consume a lot of your time so just give me a few minutes and i'll be right so i'm back uh basically what happened is this is what we are trying to do so let me just be where we was we were facing this problem why this documents is causing error well and the problem is firebase has seems to be updated their packages so the first thing is don't use like this so i'm using them without mentioning their you know the version code what i will do is i will mention all the latest version code in the blog post so visit the link and make sure to use the right version because they are kind of updating this very frequently i don't know why but this documents was working yesterday but it's not working today so what uh what has changed let me just yeah so what has changed is now this documents is called dogs and if you save that it's working so it's fixed but just make sure to visit the link link in the description which is the blog post where i will be mentioning each and every uh latest version of all of these okay so we have the image you can see but that's not exactly how i wanted that so let me just give it a quick height so maybe i just want it to be a height of 30 i want the width to be weird oops like width to be 30 like that looks good okay okay but i want this to be a bit more customized i want more information to be visible so i'm just going to go ahead and create a widget for it now this particular widget is going to be called search list user tile this is just the name of the widget you can name it whatever you want i'm just going to name it like this now i'm creating a row because i'm going to have the profile picture the name and the email id like that so i'm going to first say row inside the row i'm going to have the image where is the image i think i've copied that from here no it copied so i'm just going to cut it from here and paste it there let me end it with a semicolon so this is an image we have an image okay we are not going to use it like this let me just have it there and i'm going to accept it like this so i'll say profile url okay and what do we need more we will need a string name so i'll say name what do we need uh anything else we need email so these are the different things we also will need um anything else i guess uh that will be it right so i'll remove this sorry i need to provide that here i'll remove this what's the problem no okay i don't care problem okay so let me do this quick let me copy the search list user title and paste it here and run like that this is just the one value so we need to provide three of like oh sorry what am i doing i'm going to copy that just give me a second i know you guys may be thinking what what are you doing give it give it a second and explain so what i did is i was just directly returning this image widget now i have created the separate widget called search list user time which is going to accept profile url name and email and now i am returning that so right now i am providing these three values and these are just same so first is actually the profile url so it is a profile url so it is perfectly right the second one is name so what is the key for the name it is name so i'm just going to go in here and i'm going to provide that key name now the third one is email so what is the key for the email it is email so i'm just going to provide that e mail so now i will have all these three values and now i can show them now i'm using column because i want to show the name and email one about the other like that kind of stuff so i'll say sorry let me get rid of this column i'll say column and inside of that children okay it's not seems to be very happy with me uh first thing first i'll show the name uh the name will be above and the email will be below that and then we will have the text we will have the email in here so i'll just say email and i'll save that so if i'll go here you can see it looks like this so i want these uh both text to be aligned from straight start so how can we do that we can say cross access alignment what is cross x's alignment for a column the main axis is the uh vertical one so in the cross axis i wanted to start from start so i'll say cross axis uh alignment dot start so now you can see i want a little bit of space between the image and this so i'll say size box and the space i want is horizontal so i'll save it let's just go with eight i think it will be good enough let's go with 16 maybe 12 is good enough i guess anyhow i want to provide my image a little bit of a border radius to do that you can use clip r right and then just provide the border radius so i'll just say border radius dot circular let's go with 30 so you can see it's perfect circle uh i think a little bit of a bigger will not hurt a lot so i'm just going to increase the size of the image like that and i guess that's all i mean what do we need more um we want to implement a click on this so that you know when the user will click on this particular um tile then the user can open up the chat room so for that i can just wrap my row inside a widget called gesture detector and over there i'll have a on tap functionality inside the contact functionality what i'm going to do is i'm going to say navigator levy okay door dood push now you see i'm not using push replacement because i want user to be able to open this chat and click on back and be able to come back to the home screen so i'll say material page row and this will take a builder builder will basically ask from where to where do you want to go so context will say that i am here and i want to go to conversation chat is clear actually chat screen and there we have it we can go but you know what chat screen wants to know where what what is the username of this user and what is the name of this user username will be required so that we can create a chat room id with that user and the name is required so that you know we can show that you know you're talking with this particular user so i'm going to say final why am i saying final because the values which i'm going to accept which is the chat with username user name this is not going to update right the username of the other user is not going to update so to accept these values we are going to use the constructor we will say this dot chat another name right uh simply like that so i hope this is clear uh final because these values are final they are not going to change this is how we accept the values by a constructor now we have both these values we also need to provide these from here so let's go back the first thing was the username so where is the username we are not accepting that interesting so let me just accept the username as well now once you cross this kind of three four values mark i will always recommend to wrap it in this curly bracket so now what will happen is you will be providing the values with the keys so this is the profile url so you will mention it is a profile um then this is an image so you will mention it is an image then this is a name so we will mention it is a name and then provide the value if it is an email then you will mention it is an email and then you will provide the value if it is a username you will mention it is a username and then provide the value because sometimes what happens is you know you provided one value before and one value after that is again a problem for the debugging because later on this is not a problem which your editor can understand so hence you will not be able to debug this easily which will cause a lot of time consumptions the username and username basically is the keys there we have it so now we have the username here so i can provide the username and then the next thing will be named so we have both of these values available now so if i will click on this we are in the chat screen but chat is screen just a scaffold so i want to show a app bar in here so i'll say app bar and apple will have a title title is nothing but a text and text will have a string what is the string which we want to provide to the text our text will be name but one thing which we should which you should know about is you cannot directly use the variables which you accepted in the stateful widget you have to mention widget dot that particular variable so now you can see we have the name of the user which we are interacting with right above here okay so now what i want to do is i want to generate a chat room id so that i can check if that chat room exists or not if the chat room exists which means i have already contacted this user then i would like to get the chat of uh the last chat which we have right you know i want to see what we talked about and uh then we can continue chatting so first thing first i'll just go in here and i'll say string chat room right the second thing is going to be the message id so i i showed you an interesting feature initially which was uh then that you know when we are sending a message uh we are actually making it more real time right it's a user don't have to wait for our uh whole message to complete uh if you think of it like invoice so for example when i'm saying something you're hearing you don't have to wait uh until i i completed my whole sentences or a paragraph to start listening to it you start listening it at a real time right that's a kind of a chat functionality which we added that when you are writing your message it will be instantly visible to your uh the person on the other hand so he or she don't have to wait for your message for a long time right so for that i'm going to have a message id which is going to be same for all of these so i'll show you how it will work but this is the reason why i'm using this message id okay um other values like for example i will be using my name my profile pic my username my email a lot right so that's why i'm defining the variables for this all these values will be got we will get these values from shared preferences so let's just uh get this quick so i'll say get my info from uh shared references preference that's fine okay so now in here we know that shared preferences function will be async asynchronous while making i'll be making my function asynchronous and here i'll say my name is equals to already shared preference helper dot like dot dot oh my god dot we need to first import this i think i misspelled something but i think i haven't okay so there we go um and inside of that i want to say get name i guess uh username no display name correct okay what do we want more i'll add a semicolon just to remove this what is the problem i know okay now it's fine now i'll say my uh what do we need to profile pic is equals to await and then i'll say shared preferred preference helper and then i'll say dot get what do i want to get i want to get the profile url what's next well next is username so i'll say my username is equals okay dot get user name there we go then what is next we want the email so i will say emails equals to update shared preferred source and push and then dot get user email there we go we have all the information available now what do we want to do well we want to create a chatroom ide there we go chatroom id is equals to well i'm going to actually you know create a function for uh generating a chat room id and here is how it works get chat room id by user names so i'm generating a chat room id by the username of both of the user so we are going to have a string a string b so a is a username of one user b is the string username of another user so how this will work is we will say if a dot sub string zero comma one dot code unit at zero greater than b dot sub string zero comma one dot code unit at zero so we are basically testing which string is um greater than which is which is not because what i want to do is if i'm providing two strings to this chat room id i wanted to always generate the same chat room id so we will have two usernames so let's say one user name is samsung's karthivari and the other username is the indian guy so what i will do for the chat room ideas i will have the username and then underscore and then the other id now what i want to do is i want to make this function so that i can provide these values in any manner and it will always generate the same id whether it will take this first or this first it does not matter right so that's the whole point of this function so now this will return um dollar b slash underscore uh dollar a semicolon why did i use uh that kind of slash because sorry where is p yeah so the reason for using that slash was because if you are defining a variable with this dollar sign uh how do the compiler will know this variable is not continuing right so in that case i'm using slash so that the compiler can know you know uh that this variable has ended here and this next part is actually just a string okay so if this is not the case then what will happen we will return a first and b after that something like this okay so to get the chat room id by the username what you will do is we will provide the username so i'll say widget dot uh chat with username so this is the other person username who you was searching for and then my username my username like that there we go okay so now we have the chatroom id what do we want next well now we will uh go ahead and create the init function so that in the unit state we can do this on the launch so when this particular screen builds for the first time i would like to get my information right so these are the things which i want to do on the launch of this screen so all of those will go inside this init state and i will create a separate function which will take care of this so i'll say do this on launch okay so what do we i want to do on launch well first of all i would like to get my information so i also get my information shared preferences and second will be to get and set messages so i'll create a function in here get and set messages so according to the uh chat room id generated we would like to get all the messages if any in that particular chat room right so for that this is the function so i'm going to call that function as well now i would not like to call this function before i have gotten these values so i will wait for this again why am i waiting for these values well because i'm getting them from from the shared preferences and when we get a value from shared preferences it takes time okay that makes sense so if you're using a weight you need to make your function what is synchronous so that's there we go now i will be calling this function here there we go and that's for that okay so so far we have generated the chat room id we have all the all of my information of we can say the logged in user information we are generating the chat room id what is next well let's go ahead and build the user interface of this screen so let me just generate a body in this one so the first thing which i want is i want that message option so i can you know type it up type out a message and i can click on send and send that particular message so let's create that so it will start with the container so i'll say container then we will have a child which is going to be stack now you will be licensed what is a stack and why are we using it well stack is something which we use to align to a particular widget one above the other something like if you have used android then we do this by using relative layout if you have done anything with web development we do this by you know making the position absolute and stuff like that but at the end of the day stack is used to align two widgets one above the others just like a sandwich or a burger i know you may start to feel hungry don't leave the videos to get something to eat and continue okay so what we need now is um basically why i'm like uh positioning two widgets one above the other is this uh we will have our whole chat screen here uh or like the list of messages and above those we will have that message box so the reason for having it above rather than just below is if i will click on it it will go above the list and we will be able to write the message properly so that's the whole point of it okay so without any discussion any longer i'm just going to go ahead and create that amazing chat message box yeah we can call it a message box right where we will be writing out the message so it is going to start with the container the container will have a child child is going to be a row again y row because row helps us to align two widgets horizontally and we will be having a text field and an icon to send the message which are going to be aligned you guessed it horizontally so i'll say text field and then we want an icon for icon we are using a material icon which is going to be the send so that's why i can just say icons dot sign now whenever we use a text field inside of a row what do we do what do we do what do we do tell me we used a expanded widget okay we have that and you can see it's above there but do we really wanted that position i don't think so i'm going to go in here and i'm going to wrap my container with another container so i'll say container is wrapped with another container there are another other options as well for alignment don't worry but i want to keep it as simple as possible for you guys so i'll say alignment dot bottom center you can see it's aligned at the bottom now correct you can type it out and there we go it works right now i don't like this border bottom because that's kind of the design which i am going for so i'm just going to get rid of the border i i will also provide a little bit of a hint similar to what we did with our search box so how can how can we do that well you just have to go inside the text field say decoration you know we are decorating you so then i'll say input decoration and inside the input decoration we have both the options the first is the border which is will take input border dot none to get rid of that you know kind of that uh underline thing and then uh to provide a hint uh text we will say text and we can say type a message and there we go you can see that we have this type of message option available uh i don't know why it looks too odd to me is it to you i don't know like if it does look a little bit odd you can always go ahead and provide a hint style where is it hint style so if you want to i don't know maybe increase the font size of a font width or weight of it so i'll say font weight and i'll say 500 sorry we don't define it like that we say font weight dot 500 i think now it looks good maybe four should be good enough i think it was already four what about 450 i'm not sure if we can go for 450 let's just go with 500 i think that looks good uh maybe not i don't know i'm not able to decide which one looks good so i'll i'll i will leave it to you decide accordingly and you can use now i would like to have a little bit of a space um both the side it looks really kind of compressed kind of so i'm just going to go inside my container and then um let's provided a padding so i'll say edge inserts dot i want the same horizontal padding so i'll use symmetric i'll say horizontal and i'll provide around 16 and i want a little bit of a vertical but of course same from both the ends that will be around 8. so you can see now it has a vertical padding of 8 and a horizontal of 16 not 6. uh yeah now something like that now of course i want this to stand out from the background it kind of looks um not too different right so what i will do is i'll say color colors dot black um dot with opacity with opacity 0.88 so this is just my design you you can do whatever or however you would like to have let me just make my hint text color to a little bit of a white because you know the black color is not going to look good font um no color colors dot white dot with opacity 0.6 now you may be like why since car did you provided this with opacity because uh usually the usually what always the hint text is kind of little bit of a lighter text compared to the normal text so if i go in my text field i have this style option so i can provide the styling to the main font as well which is going to be color colors dot white so you can see if i will this is a hint text type so it will be little bit lighter but if you write something in that it will be pure white i also want my icon color to be white so you can do that as well just say color say colors dot white and there we go it's done okay so that is working what do we want next we want to show the list of all the messages now so let's create that right well before showing don't you think we need to have an option to add a message right so we will create a function for that first and then we will move on to uh show all the messages so i'll say add message and i hope you know when this function will be called once we click on this and also once you are writing something here so i'll say add message and there we go now so there are two kind of add message functions which will be called one when you are just writing so it will be kind of uh basically you are writing it out and it's instantly visible to the other user and one instance it will be when you click on the send button so when you will click on the send button then you will start writing next message rather than writing that itself right so that tracking is keep making sure by this boolean value which is called send click so if this add message is called by clicking on send then we will have some things to do more to separate it to be a next message um compared to if it is not clicked by send or but it's actually you know the user is just writing the message and we are calling this function add a message okay so what i will do is i will say if we need to make sure that user have something written over here i don't want to call my add message function when there is no message right so again we have to keep a track if anything is written in the text field how do we keep a track of anything written in the text field we create something called text editing controller so this will uh this one will be called message text editing controller uh is equals to text editing controller whoa what the hell okay i i always use two t's i don't know why okay i think i need to do like okay so this is basically i define a text editing controller now i just need to go to my text field say control and provide that now i can just use that in here if this controller dot text is not equals to blank which means there is something written on the message option here then i will get that message i'll say string message is equals to message text editing controller what happened dot text okay so i i got the message in the string this one and i will clear it from there so that you know user is clear that you know something happened uh maybe we can clear it a little bit later not right now because i am calling this all the time not just when i click on this so i don't want to clear this i want user to be able to write and it will be instantly visible to the other user i hope every single line is making sense um so then we will say last message timestamp so this is the time uh when the message is sent the reason for keeping a track of the timestamp is because um we will be sorting out this list of messages by time right so that's fine so now we have the timestamp when this message is being sent i'll create a map with all the message information so i'll say string is the data type of the key and dynamic is the data type of the values so i'll say message info map again i'll be uploading this all map inside a document which is going to be inside the collection called chats now not directly here actually we will have a collection called chat rooms and that will have the id which i mentioned the id generated by this there so let's say for now just let's say something like that and it will have values so for example every single document have this user's value which will contain uh the user's username so for example we created one which is for ourselves right so i mentioned uh one will be created for i am sanskar diwali underscored the indian app guy right so i will have both the username like this inside the users array i will have i am scott diwali and i will have the indian app i like that so this is how we will create a chat room we haven't gone through that process yet so yeah don't worry about it we will create a function to create a chat room but once the chat room is created inside of that chat room we will have a collection so it will be similar to this um just where the there is users it will be chat rooms and there will be a chat room id over here and then we will create a collection inside of it call it chats and then that chats will have a document of messages right so don't worry everything will make sense just give it time so yeah we are here back so what are the different uh information about a message we want to have well the first thing is the message text so the message text is being saved as a key of message so this message is going to be this next we want to save who is the send by why am i saving who is this send by because i want to align the messages accordingly so if you open up your message messenger or whatsapp or any chat application how they work is if it is sent by myself then the message will be visible on the right hand side if the message is sent by the other user then it will be visible on the left hand side so that's the reason why i'm keeping a track that who sent this message to whom my user name so this is my username the user who is sending the message now we want to also attach the timestamp so timestamp key is ts so i will provide the timestamp here the last thing is the image url so if you would like to show the image url of each message like for example you know some message application i don't know which one but i think yes messenger have this that it shows the user profile picture with each message so for that only i saved the image url so if you would like to do that feel free to do so i am going to more than appreciate that okay and of course like you can create a pull request as well in the repo repo which i will share so that you know other people's can use it as well now let's generate a message id so if message id is equals to equals to blank so initially message id will be blank right so where is the message id blank right so if it is equal to blank which means we haven't wrote any message yet uh what do i mean by that is not that we have any message but we haven't wrote a sing uh like half message like this yet right so that's why it's blank so then what i will do is i will say message id now this is where we will be using that package which i told you about uh generating random strings so we will say message id is equals to random alphanumeric alpha and there we will provide 12 so this is the like the length of the alphanumeric key which we are generating for our message id and then i will upload the data to our database so i will say database method so let's go to the database methods and create a method for this we will be creating a method to update last message sent now i guess you may be thinking that since we haven't created the chat room yet why are you adding the message first so i think let's complete this last message send first because uh basically this last message uh update thing is going to be something which we will be updating in the chat room um okay let me just give a second so because once we will apply uh update that then only we will continue so update the last message and once we have updated the last message send then we can continue to add the message so what i'm going to do is i'm going to add the message to add the message we are going to create the function here so i'll say future i'll say add message this is a function i'm writing to add the message to the database so i think i have given you a view about how it will be structured so it will be something like this so we are going to be firebase instance then collection the collection name will be called chat rooms so just above this users we will have chat rooms then we will have a doc with a chat id you can call it chat room id string chat room id so this is the one which we are generating here right here then we have the chat room id inside of that we will see create a collection i will call that chat so i think i have mentioned that as well then i will have a doc so i am actually generating the id for document myself which is the message id this one okay this one the reason for me generating it by myself is because i want to update the message again and again so until unless you have finalized the message which means you know you are writing it down it's not kind of uh it's not send kind of right so at that particular moment of time whenever you write something more so for example you have written that much and you add m then i'm updating that exact message i'm not kind of adding one more i hope that makes sense so i'll say doc so here i will provide the message id dot set so here i'll provide the message info so i'll say map message info map and then i can just provide that so this is how we will call that add message function so let's go back and call it right so i'll say dot add message now here we have to provide the chat room id which is provided message id is provided in message info map is provided as well so the naming convention worked pretty well right so now i will go to then what is then well basically what do we want to do after this is done so this is our add message function let me go back to it so once this is done we have we are returning right so once this is let me make sure this is asynchronous so that we can actually use that then function okay so i'll go back in here and then um once this is done i would like to kind of update some values in my chat room uh so let me just you know give you an idea enough of the talk uh so chat rooms next door id so what will happen is i will generate a chat room with the individual user i am trying to talk to right and every chat room will have these particular values last message so you know you in whatsapp or in messenger they all show the last message in the list right so we will be doing the same our last message we will have last message send timestamp so that we can you know order these uh chat rooms in the home screen so that the recent chat the one which the with the reach said chart will be at the top that's the reason why we are saving the timestamp as well uh this is actually timestamp i'm not mentioning the values for now uh then we are also going to keep a track of last message send by so in whatsapp actually it shows you that you know the last message was sent by whom so we can show that as well that's why i'm saving this right so here the username will be there for the user who is who have sent that so let me just keep keep it so that you know when we created you will be having an idea so what i want to do once i have added the messages i want to update all of these because every time a single user sends a new message the last message will be updated last message send by will be updated and last message send timestamp will be updated so how can we do that well i'll create a map for it and we will upload that map to the uh this chat room id right in here so let's create that map the map will have a data type of string for the key and dynamic for the value now moving on let me just make sure this is fine let me add a semicolon here okay then we will name this to be last message info map is equals to over here we will define the first key which is last message message and this is going to be the message which we saved above okay over here this message then uh last message send timestamp is going to be the last message and timestamp so actually i was you know datetime.now i was calling this at both these places but it was creating a little bit of a difference between them because this is going to take some time and then this function is going to be called so that is the reason why i created a variable with the exact time so that i can provide the same time to the message as well as to my chat room so i'll say that next i'll say last message send by and then i'll provide the my user name okay so we have this values now we have the information now we can upload this to the database now before to upload the data uh to the database we need to create a function for it right oh my god i haven't completed this yeah uh just a semicolon was left so i'll create a function to update last message message sent okay i'll say i need in this one chat room id of course i need that why because i will be going inside chat room collection then inside the chat room id and then adding these values so i'll say i need the chat room id and i think if i will need anything else i'll accept that so i'll return firebase file store now first thing just to be clear why am i returning when i'm actually updating the value i'm not reading the data from my our database i'm actually updating it so the reason for the written is very simple because once it is updated i would like to kind of get to know about it so that you know if i want to do something about with it it will be returning something all the time so for example when we update a value it actually returns uh nothing so it will be void so you don't actually have to use it but if you want to do something after it you can do something like async and stuff like that so now i'm going to say firestore.instance. i'll say collection and the collection is going to be chat rooms i guess you know that dot document dot dot dot and the document is going to have this id of chat room id and then i'm going to say not set it's going to be update okay so i'll provide let's we are we have already created the map here this is the map which i want to upload so i'll accept it in this function as an argument and provide it here and that is all what we need to update that okay so now let's go back and uh call this function from right over here how can we call a function and we can just say database methods dot the name of the name of the function right uh what does this function need well it means the chat room id okay it also needs a last message info and then we can use the semicolon so that is all now i mentioned that we are using the send click because we want to do something if it is actually send clicked right so if i say send clicked um send click then what i want to do is i want to i want to remove the text in the input in the message input field so then you know now user can write another text so i will say message uh where it is just a second there we go message controller why controller i can say dot text is equals to blank so now this will remove the text from the text field what do we want to do next we want to make the message id blank so that you know the message id is now updated for the next message so it's not updating the last message it's actually creating a new one to get region generated on next next message set then i can say message id is equals to blank okay okey dokey so now we have a function which is going to take care of um adding the message but as i mentioned before we are missing one thing and that one thing is to create the chat room um if it does not exist of course when the user clicked on that where it is when user clicked on this particular search search item right so in that case if we want to create a chat room of course we will be required to get this chat room id for generate chat room id function in the home as well so i'll just copy it paste it here and where do we want to do that well uh where is our user list at over here so what i want to do is before before we go to that screen i will generate a random uh i will regenerate the chat room id so i'll say variable chat room id is equals to get chat room id by usernames um we have this username and we have my usernames let's say my username do we have that here i don't think so okay so let's do that i'm going to create all of this okay so basically i'm just creating these fields and i will be calling the same function get my info and share from shared preferences so that i can get my information from the shared preferences i'm not going to use the chat room id in here so i'm going to get rid of that is there any problem why is it not restructuring i think yeah there is an error and that's why so i will be calling this when we have this init function in its state so in the initial i'll say get info from shared preference so this function will take care of you know getting my information now once i will have my information i will say my username okay so what i'm doing is when someone is clicking on this listing i'm generating a chat room id now i have generated uh generated the chat room id the next step for me is going to be to check if that chat um chat room exists or not right just get that now here i'll say map i'll say string i'll say dynamic and i'll say chat room info map so just before a few minutes i mentioned that you know in the chat room what we will have is a user's array which will have the username so it will have my username and it will have the other username this will help us to kind of segment later on so to get the list of the people we have contacted we will use this right okay so now i want to upload this um users to create a chat room if it does not exist and if it does exist already we don't have to create it so that is the function of uh that is the function which we need to create next in our database so we will name this function let's call it create chat room and this function is going to accept chat room for short chat room id and we will figure out what it accepts later on but the first thing which we will do is we will say final snapshot now this is a snapshot i'm generating to get if we have that chat room uh already or not so i'm checking if we already have a chat room with this id or not so how can we check that i'll say await firebase firestore file store where is my store dot instance there we go and dot collection and then i'll say chat rooms okay then i'll say doc which is this chat room id so to use await we need to make our function asynchronous then i'll say dot get so i'm basically going inside the chat room i'm going inside a document called chatroom id and i'm getting the value inside of it now you know if we have a chat room id it will give us some value if we does not have this snapshot will not exist so let me check that if snapshot dot exist if it exists it means that chat room sorry chat room already exist so if chat room already exist we won't we don't want to do anything i'm just going to return true but if it does not exist then let's go ahead and create a chat room make sense let me just say else and then i'm going to say return firebase firestore and we can add a comment as well chat room room does not exist okay so i'll say filestone.instance dot dot sorry dot collection first to collection and then which collection we want to go inside the chat rooms dot dot and it will be chat room id which we are accepting here dot set and we need the chat room information which is this chat room info which you want to upload so i'll accept that in here i'll say map and i'll accept that value and i'll upload this i want you to pause it and make sure you are clear with this function all we have done is we got the value with that chat room id and we tested if that chat room exists or not if it exists then we don't want to do anything we just want to send the user to that next screen and he can continue chatting but if that chat room does not exist then we will create that okay i'm coming back in here let's see how we can call that function so i can say database methods dot create chat room and i can provide the values and that's done i hope there's no questions regarding this if you have any questions feel free to comment them down below i'll be more than happy to help you with that okay so we have all this process done we are creating a chat room we are testing it if it exists and stuff like that we are adding a message now all it is left is to fetch the list of all the messages inside this particular chat screen so if i open up the chat screen i would like to see all the messages or if we are over here then i would like to see the uh list of chat rooms so people i have already contacted with okay so let's continue okay so um as i said we have two things to do first we have to fetch the list of all the messages we also have to fetch all the people we have contacted with now the messages part is going to take a little bit of more things to do um so yeah let's let's move on with that so the first thing is i don't know why but this click is not working so this on tap which we implemented it's not working for some reason so i'm going to re reload the application and of course since we have already implemented the persistence we know that we will be in the home screen once this application restarts right so let me just first cancel close that what is happening i have no idea no idea no id and no idea let me just close this run it with again okay so just giving giving it a second or so to run okay okay okay okay so i think i was doing wait a second where did i edit the dart html that is not good that is not at all good um oh my god that was not something i wanted to do where have i done that no okay i added html for some reason i don't know how it got added but that was the problem man so i'll just restart the application again and uh invalid file okay all the problems are go you know happens when i'm recording i don't know let's give it a second i think this is not an error yes it is not it is not an error okay okay okay please run um okay there we go okay so you can see we are in the home screen i can search for the user so i want to search for i am since car tewari this user and i can click on search and there we go hello there we are if i click on this we seem to be okay so it says substring was called on null okay okay okay okay so if i go to my home screen it is saying sub string was called on null where am i calling the substring actually okay okay so i think um first of all where is this so search user list tile there we go now this is the uh i don't know where we are using the sub okay we are using substring in here so i think we are not able to provide either my username or the username which we have from that so we are actually accepting the username we know that but i'm not sure about my username so let me go back to the init state and see if i'm calling this so i'm calling this get my info from shared preferences and then i'm getting my name from there so if i go back in here i'm getting my username am i getting my username i am getting my username so that should have worked i'm not sure why it is not kind of because the init state should be called right this in its state it's calling this function okay i think i'm getting the point i am getting the point maybe i am not sure okay let me just restart this application i don't know why it's causing this error but um if i search for the indian sorry i need to search for the other user the indian actually is one my sons search for this click on that it's not happy what is problem let me just go ahead and see that again okay so it's not receiving any value here okay for a itself so i i as i said my username is something which it is not able to get and [Music] i don't know i think i need to set state i don't know set statistics it is not something i think i need to do um but let's try that out um okay then i'll say i am scared i'll click on search click on my name okay again the same problem it is saying that a substring was called unknown so again and again this is just saying that you know we don't have your my username so to test it out i'm just going to go in here i'm going to say print this is the values we have haha and now okay i can print out these values this is just a basic um kind of log i'm doing so that i can see what i actually have so i'm just going to restart the application and i'll say i am starting yes because i am and if i click on that you can see haha no we cannot even see that haha okay it says uh tab recognizer send tap down button one it does not seems to be clicking it right let me see if it even called this or not no it is not okay i i think i got the point somewhere we are already calling this so we are calling this only here okay this is not making sense okay so here it is this is the values we have haha so you can see my username is null initially right which actually is not making sense to me because i am actually providing the value via get username so with getusername we are getting the username key and i need to make sure i'm saving the username so username key username so i am let me check if i'm saving the username or not so i'll go into oauth.dart and i'll say username and guess what am i awesome or not yes you are awesome but you're done so i need to go here and say username and you just like basically i was not saving the username and username is very simple thing we need to just say replace all the gmail.com with a blank something like that okay not replaced so i was not actually saving my username hence it was not accessible so i will log out sign in again and all of this will work okay okey-dokey okey-dokey you know i think i should implement a loading you know while the loading is happening subscribe search click on this we are here so what is next what is next what is next what is next so you can see the values now we have both the values now i think we don't need that kind of a log okay clear it out okay so now over here i would like to fetch all the messages um which are added to the database but let's first add a message so if i will take it here uh we have this chat room created you can see we have the chat room created now i can delete the one which we created before so i'm going to add a message so you can see i'm just typing message but i'm not actually calling this function so you know what i need to call this so i'll go to the chat screen and what i need to do is i need to call this add message function whenever there is a change in my text field so whenever you write something in the text field there is a function called on changed which is called and it will it returns the value which is written um basically what uh what is the value in the text field so i don't i'm not too much interested in that i just want to call this add message function whenever this is called now the reason for mentioning this to be false is because this is not send button clicked okay you can see send click it's not a send click and another time which i want to do this is i want to do is when someone click on the send icon i will add a gesture detector to it gesture detector so that i can keep a track of that on tap functionality and there i'll say add message and over here i'll say true because this is the send clicked clear so if i go back in here i clear this out now since it is changing i am expecting to be adding the last message updated you can see it is updated quite many times and if i'll reload i am expecting to see that chats collection to be visible not sure why it is not added okay it is added you can see we have chats and this is the message we have so you can see when i'm writing something in this message new message is not added it is updating just this one right and if i'll click on send and i write one more message you can see then new message is created so that was the whole idea of message id and everything now i have two messages let me add two more okay and now let's fetch these four messages to fetch these messages i'm going to go inside the chat screen i'll close all the others and what i need to do is whenever i'm opening up this particular screen of chat screen i'll be fetching them so as i said before i am i have created this get and set function for exactly that reason so um we will be generating a stream of messages to make it real time because the whole idea with messages is that you don't want to refresh or go back and open this screen again and again to see the latest messages you want to be on this screen and see the real time updates uh changes instantly right so to do that what we will be required to do is to generate a stream of messages so i'll go ahead here and i'll say stream and i'll say stream message stream there we go okay i'll go i will grab that stream of messages i'll say message stream is equals to um we need to create a function inside data database methods and that function is going to be called get chat room messages so i'll just go in over here and i'll create a function called get chat room messages let's just message okay chatroom id um and i'll say synchronized and then over here we will say return oops caps lock is on no it's not so i'll say firebase firestore dot instance and then i'll say dot collection and that collection is going to be chat rooms and then i'll say dot document and this document is going to be what chat room id then we will say dot collection and then i'll say chats dot snapshot so this is how we get the data how do we get the data first we provide where do we want to get the data from so i said i want to go inside the fire store so this is what the two words means then i said i want to go inside the collection called chat rooms which is this one then i said i want to go inside the document with this chat room id then i get into this one then i said i want to go inside the collection charts so then i go inside this one and then calling this a snapshot will provide me all the documents now i don't want these messages directly i want to order them by the time step and order them actually descending descend okay i don't know what i'm doing uh c e n d i n g okay ascending so that will be true and that's all so the reason for ascending is because i want the last message to be at the top now you will be like cisco what you said at the top no the last message will be at the bottom but what i'm going to do is i will make the last message at the top and i will reverse this list so basically what happens is you know what you know what let's keep uh let's um i will show you with and without it so that you know you get the point of what i'm trying to do you know that that much i'm working hard to explain you everything if you haven't clicked the like button yet i mean seriously that is the least you can do please okay so what can we do next we can call this function right so first let me define what is the written type of this function which is future so i'll say future then i'll say stream and then i'll say query snapshot and then i'll make it like that okay so we are going to return a query snapshot of stream so which is actually a stream so now i can go in here and this message stream can say dot get uh chat room messages and we will be providing the chat room id and then i'll say turn done now this is going to take some time so we need to make that to be await and save that we are already calling it so we don't have to worry about that so we have the messages in our stream now what is the next thing we would like to do we would like to show them in the list so we will create a widget we will say messages um similar to how we then uh before we will create a messages uh list okay which will have basically the image on the message and who it is send by so i will call that let's say chat messages and then uh inside of it i will return a stream builder what is a stream builder well whenever you have a data from the stream you will be using a stream builder isn't it too simply simple to understand if you don't understand what a stream is the stream is basically kind of a flow of data so uh how this stream helps is if there is any change in the data in our database it will be instantly notified to our local so that you know we can update that snap snapshot so this snapshot is nothing but the data which we got from this stream now we will be using this snapshot to create a list view so i'll say list view dot builder now one thing is which is very clear about list view dot builder is it needs two most important things first is the item count second is the item builder so item count is going to be got from the snap short dot data dot docs yeah we just saw that yes remember it was causing an error before so in the list view builder we will have a context and we will have an index then we will return a simple text for now okay so as we did before i am going to create a document snapshot which is going to be dx is equals to snapshot dot dot data and end it with a semicolon then i'll use this ts and then i'll provide the key so what is the key for our message i just want to show the message which is this message m e double s a g e so make sure this is exactly spelled at there and just add all these semicolons and now we will be using this widget to show inside our body so inside our scaffold body not our body so there we go we have a problem because um we haven't uh you know got this we just added this so we don't actually have a stream of data now so this is null for now so i will check that that if snapshot dot has data then only show this list view builder otherwise just show a circular progress indicator and i'll wrap that circular progress indicator into a widget which is a center widget so that you know circular progress indicator is in the center now what do we want now do we want let's just reload this why am i reloading because i will open this screen again so i'll say i am so scared search for that user open the chat and i am expecting to see these messages it should not take that long time i'm doing that right right i'm using the docs i'm using the ds okay i'm not setting the state set statement set state and save exactly so we need to set the state so there we go you can see the messages but you will be like subscribe this look this is like the ugliest message i have seen but don't worry we will make this look quite similar to messenger uh something like this you know like a blue and a grey kind of shade okay so how can we do that well i will make my phone here first little bit to the side and let's go for a little bit of a makeup for for our chat messages right so um how i'm going to create that is i'm going to create a widget called chat message tile and this this is basically a single message right it's a single message um widget so it will return a row uh we you know what just return a container we don't need too much things uh and that container will have a child of text and that text is nothing but the message so i'll say here string message message okay so one thing which happens uh in messenger is that messages does not start from the top but they start from the bottom the reason for that is very simple when you write a new message let me fill this up okay let me just fill this up a little bit so that you can exactly see what i'm trying to explain to you um to fill this up let's just give it all the different styling which we want to do so the first thing is i want to give it a little bit of padding you know padding means like it should look a little bit full it's looking too much like very thin kind of i don't know i thought should we go for symmetric i'm just going to give it 16 from all the sides okay it's not going to work because we are just returning text here i'm going to return that and then it should work you can see oh my god i think it's too much right what do you think uh okay so we need to provide it a color as well so i'm just going to say padding is fine but we need a color so what kind of color we want so i'll say colors dot blue for now uh comma save okay so that's too much we need a little bit of a margin so i'll say margin margin will be you know a bit of a difference so margin margin will be edge inserts and we will say symmetric horizontally i want a margin of around how much should we go around 16 would be fine and vertical uh we don't want too much so i'll just say four i just want a little bit of a separation so were taken okay see okay i need your comment okay so now you can see we have a little bit of separation now of course if the text is blue i would like to have the color of my x to be white now you will be like don't make it fix we want this to be you know changeable so for example for my messages it should look blue and for the other person messages it should be looking like a little bit like a black and a grey combination so don't worry we are going to do exactly that now before we do i want to add a little bit of a padding to my list view at the top so that's what i'm going to do in here i'll say padding well you know what yeah padding is edge inserts dot i know i need a little bit of a space like uh the height of this message box i don't want my message to go below that so i'll say i want a symmetric let's see only because i want an exact to be from bottom let's say that to be around 80. okay i guess that's more than what's required 70 is fine yeah uh and i want from top around 16 so you can see from top okay so now here's the problem guys if i enter a message you can see that messages below this particular one right if i will send that you can see it's blow and if i write one more it adds to below that like it it goes more and more below that so that's not what i want i want whenever i'm writing a new message it should be instantly visible just above my message box so for that exact reason what i will do i will reverse this make it true okay and then i'll go into my database and i'll make this descending now of course this may uh okay i don't think so so if i go back i say i am saying i open the chat you can see now it's starting from the bottom and if i write a new message it start over here rather than starting uh from below this right a much better user experience okay okay since car that is fine but i don't like how this looks like i want this to look like a little bit like messenger correct those so we want to give it a border radius so let's see how we can do that so i'm going to go to my chat message style i'll remove the color why am i doing that because i'm using decoration why am i using decoration because i want to provide the border radius okay so if you want to provide water it is can we use uh we use decoration right yes we use decoration to provide uh provide the border radius i'll say circular uh i would like to have it around 24 and whenever you are using decoration make sure to provide the color inside not outside okay now you will be like since car this is not how we wanted this to look like and i will be like okay how do you want this to look like first of all it should be like message should not be equal size so that can be fixed by wrapping it in a row okay that is fixed now what do we want well we want that we should have a shape like a uh not a not you know as you can you see in messenger we don't have a whole circular from all the corners we have one corner left right so that's what we are going to structure our uh code with right so how we can do that is we are just going to go here in the board radius and i am going to just say border radius dot only and in that i'll add top left okay in top left i'll say radius radius dot circular and i'll mention that to be 24 okay then i'll say bottom right so i'm just providing radius at each individual corner and we will handle where when to show according to who sent the message so i'll accept that value as well that boolean send by me so i'm accepting that is it sent by me or not if the message is sent by me or not so i will say my username okay is equals to equals to the username which is updated for the message so i will go over here paste it there and i will where is our database we will go into our database in here and we know that the the key for the user name is send by so i will mention that here i'll say send i'll say buy okay so i hope this is clear why i'm saying my username is equals to equals to send by because if it is equal to then it is sent by me which will give this boolean value to be true but if it is not equals to then it will give this to be false which means it's not sent by me so now let's go back to the message style and structure it how we want it to be so let me just add a comma in here and sorry i think semicolon no yeah we need to add this border radius so let me add that here then i will add that for the top right so i will copy this and paste it here then then i will also add that for the bottom left and i'll add this and paste it here and then what i will do is now i want to make them specific not like right now i have given that radius from the all the sides but what i want is i want them to be very specific that for example i don't want these message to be this uh like aligned from the left side i want my messages which are sent by me to be aligned on the right side so how can i do that i can say main access alignment and then i can say send by me question mark so if they are sent by me then i will say main access alignment to be end if they are not sent by me may be sent by uh will send by the other user then i'll send a line to be start okay so now you can see they are in this site now this because these are the all the messages which are sent by me okay so let's move on and now i want to give that you know corner look at this at this particular position which is the bottom right so this is the bottom right so in the bottom right what i'll do i'll say send by me if it is sent by me then i want this circular to be zero zero radius but if it is sent by the other user then i want that to have a round of 24 radius similarly for the person who is on in this side um we will be using what it is called like the bottom left hand side so this one i'll say bought send by me so if it is sent by me i want the whole radius but if it is not sent by me then i'll just use the zero as a radius clear so that's how we will structure that let me just have a look looks good to me okay so we are fetching this and it's working perfectly fine i can send one more message and there we go we can send emojis as well and there we go cool so now we have all this working i'll go back and now what i want to do is i want to show the list of all the chat rooms we have available so how can we do that we will just go to the home screen where is our home screen there is our home and inside home we would like to show the list of users so how can we do that well we will create something called users list something called means like this is the name which i'm going to provide to the widgets right so i'll say users list and uh you know what let's call it chat rooms list chat rooms list now this is going to be nothing but uh there is uh the stream of um what could we call it chat rooms so we will be basically uh going inside this collection called chat rooms and we will get all the documents which have which contains this particular key and we will check if this particular array contains my username which is like the username of the user who is using the application so how can we do that well it's going to be very simple we just need to first create the function in the database to get the chat rooms right so to get the chat room we will create a function let me just okay so i'll go into uh into the database and we want to create a function to get the chat room so i'll say if you uh get chat rooms and then i'll say asynchronous process and then i'll say string so i need my name okay so i'm not going to accept it through the arguments i'm just going to get it directly here how can i get it uh i can get it from the shared references helper so i can say helper dot get user name so i can say get user name and then i can say return firebase file store dot instance dot collection and then i'll say chat rooms dot order by and then i'll say last message send timestamp okay now here i'll say descending ascending to be true similar to what why i did uh just this yeah so the reason for making it descending to be true is because i want uh the recent message at the top so for example if a friend of mine sent me a message so it is the uh so the last time stamp will update right i have told you how this works last time a message sent timestamp will update so according to that i want that if it is the if it is more right which will be for the recent message i want that to be that message is at the top so one more thing which is very important which i want is i want users array and it contains array contains my user name okay so i want this user's array to contain my user's name then only i will show that chat room makes sense once that query is fulfilled we want to get the snapshots clear the reason for me getting the snapshots is because it will be updating screen so for example if some new user sends me a message i don't have to refresh this screen to see that message pop up it will be instantly reflected once it is added to the database okay so we are in the home now we are in this chat room list what am i doing anything wrong what's wrong with this the name chat room exists okay so chat room list already exist where is that again where is that okay here we go so in this one we will be returning a stream builder that stream builder will have a stream i think i haven't specified this yes yeah so we will be uh having another stream which is going to be specific for the chat rooms string okay then i'll use that stream over here and we will have a builder builder will have a context and we'll have a snapshot what is a snapshot a snapshot is the data which is being returned by that stream with this stream we are going to generate a list view dot builder list view builder will take two very important thing the first is the item count how can we get the item count we can get the item count by using the snapshot then we can say docs and then we can say dot length right then we can say item builder for the builder we will just have to say context and then we will say index and then we will say return then we will say text and then over here we can specify stuff so i'm just going to um go inside this one and return some value so i'll create a document snapshot as i do always i'll say this hole and add this particular index so i want to get the document at this particular index and via that document i want to get some value so let's say i just want to [Music] i don't know i want to show the name or the username of the other person so how can i show that well i can just say ds.id this will give me this document id i can remove replace all uh my name so i can replace my name or my username actually my what is happening my username and i can where is my username my username okay so i can replace my username with blank and then once i have done that i'll say replace all underscore with blank so i hope this is making sense what i'm trying to do is i'm trying to i have this thing right let me just show you it here so i am removing my username which is this one and then i'm removing this so okay let me make this blank so that is how we are getting the name so i want to show the chatroom list right over here yeah so it's visible so you can see it is saying that get docs was called on null so of course it is called on null so let me go to that so initially we don't have this value because it has not run for the one time so i'll say has data question mark if it has data then only show the list view or else just show the loading so i'll say sir cooler progress circular progress indicator and i'll i will wrap that in the center widget so that it's in the center so you can see it's in the center now you may be thinking why it is not taking the whole space because it does not have that space that's why it's not in the center exactly but i think it's fine to be like that now it's a starting and now okay i think i'm not calling that or am i so i'm saying this get info dot share preferences okay okay so let me just search for this one where is it called we are not getting the value in this one right so where are we getting the value for the other one uh we are getting the value for this user stream here so i'll get this value on this as well okay we don't want to do this on search so okay where should we do we want to do this when we open this screen for the first time so i'll say get um chat rooms function arguments is equals to database methods dot get chat rooms and that's that's it actually asynchronous i need to make this um future function because this is going to take some time so this is going to be get chat rooms and it is returning a stream query snapshot so i'll say stream queries snapshot it is going to be future of that so i'll say future futuri like that and i'll save that now if i go here you need you see i need to use that away i will be calling this uh get chat rooms here and yeah i think get chatrooms should work i don't want this get chat rooms to be called before this function is completed because if this function is not completed calling we don't have my username if we don't have my username we cannot get the chat rooms so i'll say on screen loaded something like that it's just a function name guys but yeah so this is what is going to do and inside of that i can actually say async and i can wait for this function to be done then only i will continue with this one so now if i will reload i am expecting to see something here can i expect that i think so we have chat rooms we have last message sent by timestamp we have the users we have my username we are doing a lot of stuff but not okay so i think i need to set state doing the same problem i guess let's state so once we have the values we want to set state i think that's not working what are we doing wrong so we have this chat room list uh okay i mentioned you guys before string cap is important if you are using so that is something which we should make sure but again at the same time it's not showing me this text hello i don't think this is the problem so let me fix that back so the problem is if it has data then it will show this list view if it is showing this um circular progress indicator it means it does not have data and that can happen um if we are not able to call this chatroom streams i guess where is the chatroom streams yes if we are not able to call this chatroom but i'm calling this in this function which is being called for the first time itself things are not making sense right i don't know why but okay okay it's working this is not what i like but i guess it was just required to be reloaded but now you can see the username okay so now the customization part here is here so we want to get the information of the other user specifically their name their profile picture because we don't have that in this one right so we want to get that information what happened to this oh my god is it taking too much time i think it's maybe my internet or something but i hope it is clear that it is working it's just taking too much time for some unknown reason which i will figure it out and let you know in the blog post that is something which i can update quite easily rather than you know updating the video so where was he uh okay so i i was saying about updating the tile right so we don't have a tile right now so i'll just go in here and say widget chat so i'll say chat room list tile and this is going to be a return this is going to be a row you may be thinking why is we are using row because we will have an image and at the side of it there will be a username below which we will have a last message so image will have dot network so we need the profile picture url so i'll say profile pic url and i'll paste it here what do we need next uh we need the column column children's we need the text to be name of that user so i'll say name which is going to be string name and then we don't have these values guys right now that's why i'm just keeping it blank for now i'll add that once we have the values i also need the last message so we have the last message that's fine last message i'll copy that paste it here save this now so the thing which is left is we want to get the user info by his or her username so let's go to the database and create a function quick for that so how can we get the user information we can go inside the users and we can make a query that where username is equals to the username which we are searching for we will get that particular document and then we will have the access to the image url by which we can show the profile picture we will have the name which we can show and we will also have an email if you like to show that okay so i'll create this function name this function called user get user info and i'll accept a username in here how this will work is we will go inside the firebase file store we will go inside the collection called users then we will say where user name which is a key by the way user name is a one two user name dot get like that and then i can return this and of course i'll wait for it to be done so that you know i'm not returning it instantly but this is the day so this is the function get user info function we will be calling this function to get the um user information okay so yeah so i'll go in here and i'll be calling this function okay so now the question arises when should we call this because the thing is like we need to call this for each and every um what should we call it individual tile right so you know what we are going to cut this out we will create a stateful widget for this okay let me go to the bottom state full and i will call that chat room list time now how many of you got that why we created this stateful widget the reason for that is because we want to do something or think of it like running a function for each individual time separately so that's the reason now we will be accepting all these values via a constructor so i'll say this dot that this dot that this dot that this dot that okay not string what is that uh this dot okay string series no you will need the name we will need that not string we are good okay so we will be accepting the values like this these values are not not going to change we are not going to change these values are we well i think we are going to change the profile picture url because we are not accepting that um we are not going to accept the last uh this one as well we will be accepting the username though so i'll say username i mean like if you are fine with just showing the username we are done okay so we don't have to do a lot um profile picture and name okay so this is something which i'll define in here because this is the these are the values which we are going to update um profile picture and name so we will create a function get this user okay so we are going to get the information of this user uh by whom we have a chat room with so i will say user name which is basically the username is equals to let's accept the chat room id yeah that will be fine so i'll say username is equals to widget okay equal to what happened my button is not working i think it is so i'll say replace all and i'll be replacing widget dot my username okay i need to accept my username as well then my username and then i have to specify that here as well my username we will be replacing my username i think i have already cleared this that i can replace my username and underscore from the chatroom id and we will be left with the username of the other user make sense so this will be blank then i'll say dot please all and this time we will remove the underscore with blank nothing and this will give us the username of the other user so let's not call it username user let's just call it okay so we have the username of the other user now we want to get a query snap short am i what am i getting get yeah so basically this get is actually returning a query snapshot got it so you can say future queries snap short snapshot okay so this is what this function is going to return so i'm going to create this query snap short shot am i spelling it correctly where is that so yeah query snapshot and i'll create that query snapshot is equals to await and we are going to run that function so i'll say database methods dot get user info and then i'll provide the username once we have the username then what i'm going to do is i'm going to print something so this is basically the data which we are getting so i want to make sure that we are getting that data so i'll say query snapshot and dot docs then i'll say zero dot id like that and something like that so we will have that so i'll say name is equals to name is equals to query snapshot dot docs docs dot okay dogs then zero now you may be like salsa why you are using 0 well let me clear this up we are making a query whenever you do this where or order by things like that you are making a query which will kind of return a list of documents now it's us it's us that we know you know we know that we are only going to get one document with this condition right so that's what i'm doing i'm getting the first document which is at the zeroth position and with that i want to get the so this much is saying that this is the document snapshot with mentioning the key i can get the value of that particular document is it making sense i hope it is so query snapshot collection of documents when i say documents at the zeroth position this give me the document at document at zeroth position which is the document of the user for whom we searched for by the username i'm using await so let me make this say something yeah so i hope this is now making sense so this is the document snapshot so document snapshot is document inside document document is a map so document have a key value pairs to get a value of a doc and or get a value of individual value of a document we can just pass the key and we will get them so we need name we need the profile picture url so i'll say profile picture url and uh what is it called it's called img url so i'll say i n g u r l and there we go we have both of these values available so i can show that i i'm going to just say set state so that we can update the state or basically the user interface according to the latest information available now i can show this name i can show the last message i think we need to make sure this is widget correct okay so image will have a little bit of a styling a height of 30 maybe and width of 30. so if you will go in here i'll reload this screen for you i think i have to use this chat room now i'm using that last one where is that okay where is it okay i'm not using it okay um okay i'm just directly showing um the name right now which does not seems to be working i don't know why yeah it is working it was showing that so now i will return this chat list tile which needs quite a lot of values the first thing is it needs the last message so i'll say ds and i'll provide the last message and the last message for this chat room can we get uh record we can get that by using the last message key is it sim uh is it any tough i don't think so what is the second thing second thing is the chat room id i think i can directly see the chat room id no for chat room id we can just say ds dot id is it tough i don't think so then we have my username so my username my username is my username so i don't think we need to do any struggle for that okie dokie so i have this now let me restart this i don't know what i am doing but basically it is visible for some time and then kind of removes itself i don't know why that is happening i need to figure that out but in the mean time okay you know what close this run this again so what is left if you will ask me a little bit of a makeup of this um chat room list tile and uh you know what other than that all of the things are done so yeah if you want any other more features do let me know in the comment i'll try to add them in the next upcoming builds which we will do and if you haven't already visit my channel i have done a lot of different builds with flutter being it a wallpaper app news app chat application well chat we have already built and we have to do web application we have more and more so just visit on my channel by clicking on it and you will be able to find a lot of content and i hope it and adds value to so what is happening it is loading which is not something i i really like right um it is taking quite a lot of time so let's just give it a second and i can just click on save which might initiate the set state uh let me go back i don't know why it is not so i am actually you know after getting the chat uh room stream i am actually setting the state but for some reason it's not very justifiable so let me just click on it once again um this is the chat room it is returning that it is waiting for that uh okay looks like you know okay i think i know what's the problem is guys i know what the problem is we need to create a sorry sorry sorry so basically we need to create an index for this guys uh the thing is um this is a bit kind of composite query okay so we have a very simple query and we have a composite query so whenever you have a k use case where you have a kind of a composite query um what do i mean by composite query well we are using this order by with this array contains condition so you can see it is written that the query requires an index so we have to create an index for that particular query so i'll open that query again just make sure i create this so yeah so we need to basically click just wait for a few minutes this will be checked once this is checked then you can run that particular query so let's just give it a few seconds and i'll be right back okay so as you can see it's finally done and what we can do is um i just reloaded the application and it is showing this error so the error is that we are using the network image and the url is actually equals to null initially so what we have to make sure that we are not showing the widget until unless we have the values right so for that exact reason what i'll do is i'll pick this profile url and i'll go in here i'll say question mark and if this profile url is not equals to blank then only show this particular row otherwise we will just show a container so if i do that and i'll save that and yeah if i'll save that and i'll reload this again we should not be able to see this row until unless we have that image now it is still showing that exact same error it is saying that network image dot io okay so let me make sure network image okay um url is not equal to null is not true so which means this is null for some reason so i am going to do this i'm going to define this to be initially to be blank like that like that like that like that okay so if i'll save that now and reload this um i don't know if it's going to work yeah i think now it's because this so it's not showing anything um so for some reason this is not getting the profile url i don't know why so we are using this query snapshot we are providing the value i think it's not able to understand this is the string so let me just do this okay i'll say dollar sign done done okay so something like this i'm providing the value of profile url like this so if i will wrap this inside a quotation this will specify this to be a string and if i'll save that that should work so we have a snapshot and we have to get in the docs and from that we are providing the value so we are getting the name and we are getting the name and the profile picture url so for some reason i'm not sure about one so let me do one thing guys uh for the debugging process let's check if we are getting this something blah blah blah so basically just i'm just doing this so that we have a bit of a separation from normal kind of debug consoles so yeah it helps um so i i don't see this blah blah which means we are for some reason failed to load provide install module normal group it's not working i'm going to not make this condition because i want to see the error if it is happening rather than being afraid of it you know face your problems so i think my internet is bit slow i don't know what happened so i can see the last message which is interesting uh maybe the profile picture is actually just loading that's why taking time but just to be double sure let me see if we have that blah blah blah uh it says no specified url found invalid arguments for the image codec okay so i think the profile url is not something which we got neither we got the name so this specifies that there is some kind of an error which is happening here so i am actually providing the get let me call this get user info so there sorry we are calling this get user info we are providing the username of that a particular user so which is nothing but the widget room id replaces with my okay now i uh okay i think this is right but what do you think what are we doing wrong we are actually printing that so you know what let's just print this as well so i can know like you know if we are getting values or if you are not getting the value what are we getting so i'll clear this up you can see clearly we have the last message we just don't have the profile picture and the name of that user so if i see my something something i don't know if i can see that uh okay let me just reload this for some reason i don't think this something is being printed even yep i don't think this is getting printed so it says exception caught by image service so you know what we are not going to show the image if we don't have that so just hide that image that is kind of causing the issue to show the print i guess i don't know i'm going to rerun this syncing the application okey-dokey okay i want this to be loaded like this you know something one failed to load provide install module no example module found local version is zero remote version is zero and sitting the local model provides zero remote installable zero local module class provider installer okay now it's getting my into my head what is happening well the biggest thing is i am i don't want to call it but i do super dumb stuff things like you know not calling the function so let me call that function now and let me just make this something like that so we have the name and we have the profile picture okay if you haven't liked till now just do something guys i okay so i uh now let's just give it a little bit of makeup so sized box sized box and we will give it a bit because we want a horizontal space so this way we have a horizontal space i want this image to have a circular border so i'll wrap it with a clip or rack and i'll provide that a border radius of border radius dot circular and that will be around 30 maybe because i want it to be exact circular i think it should be bigger so i'm going to go with 40 and you can see it looks much better now i want the text which is the name of the user should be a little bit of a size more so i'll say font size around 16 while um i also want to make sure both of these are starting from start so i'll say cross x is alignment cross x is alignment dot start i want to have a little bit of space between them so i'll say sized box but i want a vertical space so i'll be mentioning height of around three i don't want a lot of height i just want a little bit of it um i also wanted this to be a little bit more maybe so i think that will work now if you want to show the last time stamp you can show that here and stuff like that but i think it looks good now uh one thing which yeah so here's the application you have this user i contacted i am going to click on this okay it's not working so i need to click uh so what i want to do is i want to implement a gesture detector on it gesture detector and basically whenever there will be any on tap i want to do is the same which we do when we click on any of the search query so whenever we have a search user list we have the search user tile on tap what we do we check if that particular user id exists if it does we will create that and stuff like that right so we don't have to check any of that here we know that it already exists and that is the whole reason why it is visible here so what we will do is we will just send the user to the chat screen so if i'll save this if i'll click on this you can see we are in this particular screen and if i'll update the message for example i say thanks for your time and i upload that and i go back you can see this is the last message now okay so if you have more users you can contact with you can do that and yeah major of the stuff is done so we are done with the messenger clone i hope you enjoyed the video till now please make sure to like the video please make sure to share it um in as many facebook groups as you can just just um you know it will really mean a lot uh because you know when people watch and share your feedback that you know they have completed it really means a lot and it really pushes me to create more and more content so yeah um if you like to learn more about a more flutter then just visit my channel there are a lot of content available available for you believe me if you watched all of that your portfolio is going to get enough good that you can get a good job as a flutter developer but yeah if you want to learn more be notified about it you can click on subscribe and click on the notification bell for that so i'll see you in the next video
Info
Channel: Sanskar Tiwari
Views: 45,758
Rating: undefined out of 5
Keywords: flutter chat app, chat app, flutter chat, chat app flutter, flutter chat ui, chat app flutter firebase, flutter chat app with firebase, flutter firebase, flutter firebase app, flutter chat app firestore, flutter chat application, flutter chat app tutorial, flutter chat firebase, build chat app flutter, flutter real time chat, flutter real time app, flutter realtime chat app, flutter firebase tutorial, flutter tutorial firebase, flutter full app tutorial, learn flutter
Id: 2d1fslyxBjQ
Channel Id: undefined
Length: 193min 14sec (11594 seconds)
Published: Wed Jan 13 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.