Build Note App with Firebase Auth + Firestore & Jetpack Compose + MVVM architecture

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello good ass and welcome back so in this course we are going to learn how to use Firebase together with Japan compose and will build a simple note application so the first step is to authenticate a user and allow crude operations so guys without any further delay let's cut together and build the node application okay so before we start here you can just get the initial project inside the GitHub repository so as you can see here I have added several dependencies inside www.here or you can just easily copy them and you are just good to go so now let's get started okay so the first step here is to connect our application with Firebase console so we can easily do this inside Android Studio when we navigate here tutorials and you can find this Firebase button here which is going to load up the assistant which is going to help us to connect to the console and we have to locate here to authentication and we want to select this authenticate using Google and we want to connect this to Firebase so for case here you can just click this button here okay now here under to the Firebase console has detected that this is going to be our nodes so we're just going to click here continue so that we can easily create this project here and we don't want to enable this analytics here so you can just click create project and this is just going to create our project okay so our project is ready here we can just click continue so that we can just add these applications here so you can just easily connect here now our project is already connected so we can just easily navigate back to Android studio and as you can see here we have connected here and we have other buttons which we can just easily add here the SDK but I have already added this sdks or the dependencies which we want to use them as you can see here we have already imported this bomb and this is just going to select all of the Firebase compatible versions and we can just easily use them now here when we navigate inside the Firebase console we can just come here to all products and we want to select this authentication product here so that we can just get started and now let's just get started here by enabling this authentication inside the application and we can just select our providers or what we want to use for authentication purposes and for case we are going to select email and passwords here and we want to enable this email and password and we can just easily save here and for that case here our email and password has already been added and for now we want to come here inside our project and we go to our project settings and we have to add here the we have to add the sh certificate here which we can just easily generate inside Android studio and before we just generate this we have to download this Google service station so that we can add it inside our application so for now we are just going to download this okay so now when you finish to download this you can just navigate inside the folder where you have downloaded this and we can just easily copy this and we can just easily navigate inside our build.project here and we have to select here our project and we can just paste this inside here okay now we can just switch back here to our Android View and we can just easily close this okay so the next thing we have to generate the sh certificate and we can just easily generate this from the Creator here and as you can see here we don't see where we can just easily use the sign in report so for this case we can just press this button here and we want to disable this experimental feature here do not build trade attacks and we can just click here apply and we click OK and we have to sync our projects for this to work so we can just come here and we want to sync radio project with Creator files and wait for the grader to build so the grid has finished the build here so we can just navigate inside here Android and we want to click the sign in report here so that we can just easily generate here the sh certificates now we can just select here the sh1 certificate so we can just copy this and now we can just easily navigate back to our browser so that we can just start to use it okay now we can just easily navigate here inside our sh certificate and we want to add here a fingerprint and we can just easily paste it here and we can just click save here in order to save this sh certificate and I think we are just good to go and start to code okay now let's start to code here so the first thing we want to create a repository where we can just easily authenticate our user and for this case we can just navigate inside here or not and we can just create a new package and we want to call this out Repository and we want to create here first class so we can just create here coding class and we want to call this authentication Repository okay so inside here repository we want to get the current user so we can just call this current user and this is just a normal Firebase user and now we can just use this Firebase object here which is just available and we can just call off and we want to get the current user and this is just going to return the current user okay so we want to check if the user is going to be logged in or not and for this case we have to create a function that is going to help us to design this so you can just call this as user and this is just going to return a Boolean and we can just easily use the Firebase object again and for this case here we want to check this is not going to be equal to now and for this case we know that the user has been logged in and also we want to get the user ID so we can just call this get user ID and this is just going to return a screen and for this case here we can just call here firebase.auth and also we want to get the current user and here now we want to get the user ID and here we can just call our empty if this is just going to be now okay now Focus here we want to create another function that is going to create the actual user and this is just going to be a suspend function so we can just call this create user and here basically we want to pass in the email and also you want to pass in here password and we want to have another function that is going to be the oncomplete and this is just going to return a Boolean here okay so we want to switch the threads between the main grid to the i o so we can just use a dispatcher so we can just cut here with context and we want to use the dispatcher.io and this is just going to change the threads and for this case here now we want to create the user so we can just use the Firebase object and here we want to select this authentication and we want to create user with email and password and here basically now we can just pass in the email and password and also we want to add their own complete listener and for this case here we can just check if this is going to be successfully and now here basically we can just call here on complete and we can invoke this with true and else here we can just invoke this on complete listener with a false so this is just going to bring us the feedback so that we can just easily create and we we know that we have created successfully the user and for that case here we want to call the await function so we don't want to block the main thread so beside this we can just call here await okay so this was just for creating a user now let's create another function which is just going to help us to log in a user so it's just going to be similar to this but we can just easily change here to be logged in and for case here instead of create user so we can just call Here sign in with email and password and for that case we have already completed to create our two logging and design out okay now let's create here another package which is just going to be for our login screens and other things so we can just call this login and here we can just create here a login screen and here we want to create our login view model and now this is just going to inherit from The View model and here we can just create the private file we want to get the repository so we can just call this Repository okay now below this we can just create here data class that is going to hold up a UI State because we could have numerous UI States so we can just group them inside our UI our data class so you can just call this login UI State here and here we want to provide variables so the first thing here we are just going to create a username for example and we can just initialize this to an empty string for the first and here also we want to provide the password and also we want to duplicate this for the sign up page so you can just call this username sign up and also here we can change this to sign up and also we want to create here a confined password okay also we want to create here a state if this is going to be loading so we can just call this is loading and for this case we can just initialize this to force and also we can check if this is just successfully and here we can just provide the sign up error and also you want to create the login error and we can just initialize this to be null for the first time okay now we can just jump inside here our view module and now we can just get our current user so we can just call this current user and here we can just call this repository.current user and also we want to create another variable here and we can just call this as user and this is just going to return a Boolean and we can just Define here get function and here we want to call our Repository dot has user and for that case we are just going to get the user okay also here we want to create our login state so we can just call here login UI state and we can just create here immutable state of and we want to call here a login UI state and we want to import these values here okay now let's create our events which are going to modify our state so we can just call here and here we have to specify this to be private set so this can be only modified inside here our our view model and also now we we can just Define here our our events which are going to modify the UI so we can just call here on user name change and here basically we can just provide username which is just going to be a screen and we can just call here login UI State and we want to reinitialize this and we want to copy here and we can change the username back to the username which we have provided here and we can do the same to the rest of other items and here we can just call on password change and here basically now we can change the password and here basically we can just change the sign up and we can just pass in here the username and here we want to change the sign up username and also here we can just change the password and here basically we can change today on confirm password okay so these are just the events which are going to modify our state and now we want to write our function which is going to help us to create a user but first we want to validate these forms if they are not empty because we don't want to authenticate a user without any any Fields so you can just create here a private function and we can just call this value that login form so we can just call here a login UI stick and we want to get the username and we don't want this to be is black and also here we can just check here and we want to change also this is not going to be black also we can just provide another function which is just going to check up the so here we're going to validate the sign up forms so we can just call here our login UI state and here we have to check this is not going to be blank okay so here we can validate our forms so now let's create a function that is going to help us to create the user okay now let's create here a function which is just going to create a user and here basically we can just pass in a context because we want to display a toast message so we're just using this context here for displaying that and for this case here now we can just use the view motorscope and we can just launch this okay now we can just use here a try catch block here so we want this to throw errors if our forms are going to be invalid so we can just check here if this form is we want to validate these forms so we can just validate the forms and if this is just going to be true here so we are just negating this value and we want to throw an illegal argument exception and here we can just say email and password and here we can just provide the catch okay now we want to make here a function is going to be loading so we can just call here our login UI and also we want to check here if this code the confirmation passwords are not equal so you can just check here if the sign up password so we can just use here our login UI state so when this is not going to be equal so we can just throw another illegal argument exception and here basically we can just say password do not match and if we have passed this we can just use our login UI State and we can just copy here and we want to turn this back to now so we we are going to start again so these errors have been passed okay now we can just call here our Repository and we want to create the user and here we have to pass in the email and password and we can just call here a login UI state and we want to pass in here this sign up name and here we want to pass in the sign up password and here we want to check if this is going to be successfully or not and if this is just going to be successfully we can just easily toast here message so you can just check if this is successfully and here we can just pass in the context okay so if this is just successfully also we want to provide the state so you can just call here login UI state and here basically we want to pass in that successfully login and here we want to make it to be true and as here we can just create another trust message or we can just copy this and here we can just call it fail and for that case also we can just change here UI state and we want to make a Success login back to First okay now let's deal here with our executions and for case here if we get any exception we can just call here our login UI state and we want to pass in here the error so we can just call here copy and call the sign up error and here we can just get the exception.localize the message which is just going to give us the error and also you can just call here e.print structures so that we can just get this to our local and for that case here we can just call here finally and for this case here we can just call here login UI state and here basically we want to disable the loading progress bar so we can just call here login UIC dot copy and here basically we can just change is loading back to force okay so I think here this is just our function which is going to help us to create a user so we can just easily copy this and we want to duplicate this again and instead here of creating a user we're just going to call this login and here basically we can just remove this validation here because we're just going to use this single validation here and here we want to call validate forms so we want to check if the login forms are empty then we have to throw this illegal argument exception and for this case here we can just pass in here the sign in error and instead here of create user so we can just call here login and basically here also we want to change we want to use the username and also here we want to use the password and also we are just going to leave this every thing as is because we know that and instead here we can just change the sign up error here to be a login error and here we can just easily leave everything as they are okay so I think here if you want is complete now let's navigate inside here login screen so that we can just start to create our login screen so let's create here new composable and we're just going to call this login screen okay now let's create here at several parameters so we have the login view model and we're just going to make this nullable and because we want to use a preview function so we are just going to pass this to be null and here we want to provide the on navigation so you want to call this on navigate to home page and this is just going to return nothing and also here we want to navigate to the login page so for example here we want to navigate to the sign up page okay now let's create here an instance of login UI and here basically we can just call here login view model and we can just easily get our UI State here and also we want to check if there is an error so we can just call this is error and now we can just use here our login UI state and we want to get this is not going to be equal to null so we know that this is just going to be an error and also we want to get the context so we can just call here context okay now let's create here a column and here basically we are going to pass in a modifier and we want to fill the max size and here we can just pass in the horizontal alignment and we want to Center everything horizontally okay now let's create here our first item we are going to create here a text and we're just going to call this login and here we want to provide a style and we can just use here a material theme and we want to use header 3. and also here we want to provide the font weight and we want to make this black and also we want to change the color so you can just make this material theme and we want to use the primary color okay so the next thing here we want to check if there is any error so that we can just display it here to the user so we can just check here if it's Error and basically now we can just show the user that we have an error so we can just create here a text and for this case here we can just use our login UI state and we want to check for login error and if this is going to be null so you want to call this unknown new unknown error and here we can just change the color this we can make the color red okay also here we can just create a preview function and we can just call this brief login screen and here basically we want to show the system UI so we can just call here show system UI and we can make this to be true and here we can just call the not theme application so the not theme function here and basically we can just call here our login screen okay so this is just a preview here now let's continue to add other items okay now let's create here an outline text field and here we want to pass in the values so we can just use our login UI state and we want to select the username and if this is just going to be null so we are just going to pass in here an empty string and here on value change so we can just use see our login view model and here we want to call there on username change and basically we can just pass in here it so that it can just reflect that also here we can just easily pass in a modifier and we want to provide here a padding of 16 DP and also you want to fill the max the max width okay so let's provide here a leading icon so this is just the icon before the text field and here basically now we can just provide the icon and we can just use the icons here and here we can just provide this person here and basically here we're going to pass in to be null okay also here we want to pass in a label so we can just call here label and here for example you can just call this to be email and we want to make this text field to show an error if there is an error so we can just call here is error so this is just going to automatically change the color of the text fields okay now let's create here a password and we can just easily duplicate this and instead here of username we can just easily pass in here password and here we can just call on password change and here we can basically use the logs here to show the icon and here we can just change to the password and also here we can add one item which is just called here the visual transformation which is just going to transform this to hide the the password which is entered so we can just call here which password visual transformation okay now let's preview the changes we have made okay so I think everything is looking good now let's finish up to add other items okay now let's create here a button which is going to help us to submit these forms and here inside the on click so we can just create here a text first and we can just call this sign in and we can use here login view model and we want to log in the user so you can just call here login user and here we want to provide the context which is just we have created above there okay now let's create here espresso and here we want to create a space of 16 DP so we want to create also the text here which are going to ask the user if they don't have an account so that they can sign up so we can just create here row and here we can just pass in here a modifier and we want to fill the max width and here we want to pass in the horizontal arrangement and we want to arrange this to the center here okay now here we want to provide the first text so we can just provide here our text and also we can just create here a spacer of 8 DB and also here we can just create a text button and here we want to and we can just call this sign up and here we want to invoke our navigation so we can just call here enough to sign up page and we can just invoke here if the user clicks this button here okay now let's preview our changes we have made okay so far so good so I think everything is looking good now we want to display here the progress bar if this is going to be loading so we can just easily navigate here and create an if statement so we can just check here if our login uisd that is loading and this is just going to be equal to true then we have to show the circular progress bar so we can just call here cycle of progress indicator and for this case here we are just going to get this loading or spinning animation and also here we want to create a launched effect so when the user is successfully launched the in we want to navigate to the home page and for this case here we can just use here a login view model and we want to check if has user and we are using here a launched effect because this is just a side effect this has user here is going to arise from Firebase and not jpeg compose and for this case here we could have multiple changes and this date will be out of sync so when we are calling here launch the effect is going to smooth everything and launch this whenever this has changed as user is actually changed and then we can just run this block of code here and now we can just check here if login view model and we want to call this as usual and is actually true and if this is the case then we want to navigate to the home page so we can just call here on navigate to homepage and we can just invoke this function and for that case when the user is successfully logged in then we can just actually navigate to the home page okay now I think here we have finished to create our login screen now let's create here a sign up page and we can just easily duplicate this and we can just modify this same screen here in order to match our sign up screen and instead of login screen here we can just call this okay now we can just easily change here a login error so we don't want this and first and foremost here we want to navigate to the sign in page here so for example here we can just change we have to navigate here to the login page instead of this Ina page and also here the login error we have to change this to sign up page I would sign up error and everything will leave them as they are okay so also here we have to change this to be sign up and here we want to also change this login error and we have to change this to sign up error and then everything is okay and now let's navigate here inside our outline text Fields here and instead of using here the username so we can just use the username and here on username change we can just use on username change and we want to use the sign up thing here and everything is okay and also we can just easily navigate here inside our password and here we want to change here password sign up and here pass on password sign up change and also we want to duplicate this because we want to provide that confirmation of password and here we can just change here password confirmation and here we can just change this to confirm password [Music] and here inside the button instead of logging the user we want here to create the user so we can just call here create user and also we have to pass in here the context and we can just navigate here instead of on navigate to sign up page we can use here there on navigate to login page and we have to invoke and here we can just change here and we can just ask if the user already has an account then we can just use this to navigate to the sign up page so I think here our sign in page is ready so you can just call this sign in instead of signing up now let's create another preview function here so you can just duplicate again this and here we can just call this preview sign up screen and we can just easily call here our sign up screen and now let's preview the changes we have made okay so far so good so everything is looking good as you can see here we have all of our screens ready to use so now what has remained here is to create a mechanism for navigations and also finishing up the home screen so we can just create here another package and we want to call this home okay now let's create here a new cutting class of file and here we want to create a home page and for now here we can just create a new composable and we are just going to call this home and for now we are just going to display a text because we're just going to navigate here and later here we're going to build up the home screen here and this we can just call this okay now let's create here a new coding class or file and now we want to call this navigation okay so now we want to navigate here and the first thing here we want to create the routes and we can use an enumclass here and we want to create the login routes and here we are going to have the sign up page and the sign in page and also here we can create another enumclass and here we are just going to have the home routes and here we have our home page and also we are going to have a detailed screen and I think basically there we are just good to go okay so here we have to pass in several parameters and the first one is just enough controller and here we can just call remember nav controller and also you want to get the login view model which is just going to come from the main activity and for that case here we can just create our enough host and here we want to create our starting route this is just our start destination here and we can just using the login view model login routes and we want to select design in page and here basically now we can just create our composable okay now we want to specify here the route and basically here we can just use the login routes and here basically now we can just call our composable so you want to call here the login screen and here we want to navigate to the home page so we can just call here of controller and here we basically now we can just use the home routes and we want to pop up two and we want basically to pop up to this route here so we can just provide here our route and we want to call the login screen login routes so we want to remove this from the back stack here and we can just call this inclusive and make it to be true and for this case when we navigate to the home page when you click the back button we are going to quit the application and not going back to our sign in page or sign up page and for that case we're just going to use this mechanism here okay so here we want to navigate to our sign up page so you can just call here nav controller and we want to navigate and here we can just call our login routes and here we can just call here pop-up and we want to call here rugging routes and also we can just make this to be inclusive and make it to be true and also here we want to call launch single top and we want to make this to be true so that is just going to create one instance of this inside our back stack and not multiple instances so we can just make also this to be true and for that case we have only one item and not multiple item of the same screen inside our application okay now let's create here another composable and here we want to create our sign up route so we can just call this route and call here login routes and also here we can just call here a sign up screen and here basically now we want to navigate so you can just call here unlock controller and here we want to call home routes and we want to navigate to the home and also here we want to use this inclusive here okay and also here we can just deal with this on navigate to homepage and this is just we were supposed to call this and here is just the navigation back to the sign in page so you can just call here the enough controller and basically here now we can just call our login routes and for that case also we can just Define here another composable which is just going to be for our home screen so you can just call here out and here we want to use home routes and basically here now we can just call here home screen and we don't have anything to navigate to when we get inside our home screen okay now let's navigate here inside our main activity and inside here now we want to create a variable for our view model now we can just call this login view model and we can use a few model function here and we want to provide the model class which is just going to be our login view model and now here we can just call our navigation and basically here now we can just pass in our login view model okay now let's test our application and before we run here we call the site in report so we can just change this back to our application and let's launch this inside our app okay guys so when we'll launch our application we are just getting this error here so the default Firebase app is not initialized so I think we have forgotten to add this Insider build.gradle projects so you can just navigate here and here we want to apply this plugin here so we want to add this com.google.gms Google services in order to make it to sync properly and also we have to navigate inside here our build.grado file so here we have to add this dependency here com.google.gms Google services 4310 and now let's try to sync the project and see the changes we have made now our build.grader file has finished to sync now let's try to run our application again and see the changes so application has launched successfully however when we try to type inside this text Fields here nothing happens and this is because we have forgotten to use this view model here so we can just pass in inside here a viewmodel and also inside here the sign up page also we can just pass in here A View model and now let's try to rerun again the application and see the changes okay now application has launched successfully so here for example if we try to sign in without anything as you can see here we're getting an error now let's jump inside here our sign up page here so for example here we can just create a new email so for example here ABD and and we can try to pass in here password one two three four five six and here also you can try one two three four five six seven and then when we try here we are just getting here password do not match error so when we remove this and try again so we are going to sign in here and we navigate to the home screen successfully okay let's navigate inside here our repository and for case here now we can create here new coding class of file and for now here we want to create a storage repository so you can just call this storage okay so now before we start to create our storage repository we have to navigate inside here our clouds firestore so we are going just directly here inside our console and then we can just easily navigate here so if you don't see this firestore database shortcut you can just come here inside all products and then you can just look for cloud firestore and then select it and for that case here we have to create our database so you can just script this and there are two options to start in production mode and in test mode so for case we want to start in test mode and click next then we have to enable this okay now our database has been set up and we have this page here as you can see here we can just easily create a new collection so we're just going to come back here in just a moment so as you can see here we have several tabs here inside our Cloud firestore so we have here a tab of rules and this is just defining the rules which is going to help us to restrict the reading and writing of our document so we can just restrict for example a user is not authenticated so we don't want them to write or read from our application but for case we are just doing this for demonstration purposes so we are just going to allow read and write so if you are writing for production mode you have to write robust rules and it's just out of scope of this video and as you can see here also we have another tab which is just indexes and this is just creating compound queries so for example if you want to filter or do other things you have to write a compound queries which contains multiple Fields so for a case here we are just going to see this in a little bit because we are going to write a compound query and also here you have a tab of usage and this is just going to indicate how much have you used the cloud firestore data and now let's come back here inside our data tab okay now the first thing inside here cloud firestore is just to create a collection so you can just picture this as a folder that contains a bunch of documents and for example here now we can just create a collection and this is just a must when you want to create you want to store data inside firestore and we have to provide an ID and then provide its first document so for case here we can just call these notes and click next here and what we want to to create here first document so for example we're just going to Auto generate this and this is just going to be Auto generated even when we write it inside our code and we have to provide the first field so for case we are just going to dismiss this and click save here and it's going to save this new document as you can see here now this collection here contains one document and this document also we can just add fields and other things so this is just one note so for example if we want to add another note here we can just click here add another document and we can Auto generate here another field and we can just easily save and as you can see here so this is just going to be the list of all our nodes and you can just create another sub collection inside the document so for example inside here our document we can start another collection and this can be a collection for example inside our node we have images so we can just create another collection which is just going to have a bunch of images so for example here we have a URL to our image or a URI where the image is going to be saved and for this case we have a bunch of characters and we have to Auto generate here and we can just easily save and as you can see here now we have the notes then we have the document and we have another collection which is just containing another images and this could contain another document here for example so we have multiple images inside these images images sub Collections and this is just contained inside the document here and as you can see here now we have this document and inside here a document we can just easily add Fields so for example here we can add a field for example an ID and there are multiple data types here and when you click this drop down menu here you can see we have numbers Boolean map array null timestamp and geopoint so whenever you want this so for example here we want to select number we can just provide this to be a certain number and we can just easily add it here so this is just how you can easily add and delete documents inside a cloud firestore so for example here we want to delete and we can just easily delete a collection and we want to delete the notes collection so we can just easily click here and we are just going to delete our collection so however we want only a single collection here which we are going to solve this inside our code so we can just click next here again and how to generate this and we can just save this document here for the first time so let's see how we can just easily add and remove documents and perform crude operation using our application okay now let's create here a constant valve and here we want to get the reference to our collection so and our collection is just we can just call this notes collection ref and basically here we can just provide notes and this is just the name of our collection which we have provided inside our console here and for that case now let's create here our class so we can just create here class storage Repository okay so inside here I'll study repository first we want to get the user so you can just call here user and we want to call Firebase and we want to get the current user and also here we want to create another function which is just going to look for users if it's going to be logged in so we have what we call this has user and this is just going to return a Boolean and we want to check this is not going to be equal to now okay now here we want to get the user ID and this is going to return a string and here now we can just call here our Authentication and here we get our user ID and we're going to pass empty if this user ID is going to be null okay so we want to obtain the notes reference and this is just going to obtain the collection reference so we can just create here private variable and we are just going to call this notes ref and this is just going to be a collection reference and we can easily obtain this by using our Firebase object and we can just call here our firestore and here we have to call this collection here in order to get the notes reference and here we have to pass in the collection reference name and here is just our notes collection reference which we have defined inside our console okay so you want to retrieve the data from firestore so the first thing here we are just going to create a resource class that is going to help us to manage the state of getting this data so we can just create here a cell the class and we are just going to call this resource and this is just going to be a generic type and also here we want to provide a data type and we can just initialize this to be null and also here we have to provide a throwable which is just going to be the error so we can just call here throwable okay now here we have to create a class and this is just going to be a loading class and also we provide here type T and this is going to inherit from the resource class and here we are just passing nothing because here our throwable and also this we can just make it to be null okay we provide another class here and this is just a success class and here inside our success we have to provide the data and and also we have another class which is just the error class okay so this is just our resource class which is going to help us to manage the state of getting our data now let's navigate here and create our function which is going to get us data from Firebase okay so before we start fetching our data we have to create a model of our node which we want to save and retrieve so we can just navigate inside here our notes package and create another package and this one is we are going to call it model and inside our model class here we can just create a new cutting class or file and here we want to call this and we want this to be a data class okay now here we can just create our user ID and we can just initialize this to an empty string and also create here a title and here we can just create the description of the actual notes here and also it's Dot screen here and we can just pass in an empty screen and also you want to get the timestamp and we can use this Google Firebase timestamp and we can just use timestamp.now so that it can get the actual time and also here we want to save the color and we can actually save it as an integer so we can just call this color index and save it to be zero and also we want to get the document ID or the note ID and here we are just going to save it as a screen and also we can just initialize this to an empty screen and for that case here we have our Notes application now let's jump inside here and create our first okay now let's create here our function and we want to call this get user notes so this is just going to fetch all of the user nodes so here we can just pass in a user ID and we want this to return a flow so that we can be watching for data changes and here basically we want to return a resource and we can pass in a list of notes and we are going to use a feature of of kotlin which is just called a callback flow so this one can help us to execute or emit values inside a inside a callback so we we are just using this callback flow and we can just opt in this the features are experimented in the vision of The Cutting I'm using but the newer version of kotlin this is no longer experimental okay now let's create here a snapshot listener so we can just call this snapshot listener and here this is just going to be a listener registration and we can just initialize this to be now okay now let's create here a try catch block okay so we have to initialize here a snapshot listener and what we want to do is to create a query that is going to be sent to the Firebase server and return as a data so we have to formulate this query in the order which we want so we can just create here the node reference and the first thing we which we want is to it is to just filter this data so you want to arrange this in a certain order so you want to order by a time timestamp so we can just call here timestamp and here we have a query direction as you can see here another parameter is the query Direction so for example here if you write query the direction and you can easily create this in ascending or descending order so for case we're just going to leave the default one which is just going to suffice our need and also we are going to add another query filter parameter which we want to use this where equal to so this one is going to limit to this Fields only and the forecast here we want to use the user ID so we don't really want to return this data if they is not the user created them so we are going to provide here the user ID and that case here we can just call here at the snapshot listen and here we can just rename it so we have the snapshot and also it's going to give us an error if there is any error which has occurred so as you have seen here you can just limit this from the client side and from the server side so if you want to use rules to restrict this so you can just easily use the rules so for Simplicity we are just going to limit this from the client side okay now let's create here a response so we're just going to get the response from the snapshot so we can just call this response and here we want to use an if statement we want to check if this snapshot is not going to be equal to null and for this case we know we have retrieved the result so what we want to do is to get the nodes so we can just call here notes and we want to convert this because this is not going to be known by our files so we want to transform them to get them to uh to our nodes file so we can just call here a snapshot and call to object so this one is going to transform back to our notes class okay so this is going to deserialize the data which is going to be returned so it will be in form of Json format so we don't understand this so we are going to use this to object here in order to deserialize the data which has been returned and it must conform to this style here and for that case here we have our notes and we want to emit now our success so we can just call here a resource and we have to provide our data so the data is going to be our notes and as here we know we have not got the data so there is an error so for that case here we have to create another resource and here we have to provide an error and for a case here so the throwable you can just use here the E dot course which is going to be provided by a snapshot listener and for that case here we can just try to send this result so this is just the good thing about callback flow so we can just easily emit data from the Callback and here we can just try to send and what we want to send here is just our response and for that case here we want to if there is any error when we are executing this piece of code here we are going to catch it inside here instead of rating our our application crash so we can just try send here and we can just call here a resource and we can call here e.cos and we can just print the structures here in order to manage this and also here this must close the we have to close this callback so we can just call here a weight closure and inside here now we can just deregister everything which we have registered so for example here our snapshot State listener so we can just call here snapshot State listener and we want to remove the reason and for that case we have removed our data okay so that was our first way of getting data and here we have got our user notes so we want also to Define another function which is going to get a single note so for example when you navigate to a detailed screen we want to fetch only a single note so we can just create here another function and we can just call this get not and here we are just going to define the note ID which is going to be of type string and still here we are just going to define the Callback inside here and then we can easily react to the client or the user of this function here and now we can just create here the own error so this is just going to return a throwable and we can create here another which is just going to be their own success and here is going to return notes okay now let's obtain the notes reference again so here we have our collection reference and what we want to do here is to get the document and here we can just easily use the document and we have to provide a path and this is just going to be the ID which we have generated so as you can see here this ID here is going to be generated so we want to obtain this ID here and pass it inside our function and for that case here we can just pass in the note ID and for that case we have obtained the ID so we want to get this node and we can just call here get and this is going to help us to retrieve that document and we can add here on success and we can add here The unsuccess Listener and here we can just call here our own success method here and invoke it and we pass it with the object so what we want to do is to obtain this document snapshot and we have to deserialize it to what can be understood by our application so you can just call here to object and we want to provide here the nodes and we have to make this nullable for this to work because it can be null and for that case also we have to add the own error on failure so we are going to add here the on failure listener and for this case here we want to obtain the result so we can just call here result and we can just call here the result dot cause and we have everything so here we have got our notes okay now let's create here another function and this is just going to be add note and here we're just going to Define several parameters as you can see here we are defining the user ID the title description time stamp color and the on complete here which is going to be invoked when we add the not successfully and for that case here now we can just create our data okay so the first thing we want to generate the document ID which we can just easily use the Firebase and we can just call here document ID and we use our notes reference we can create here a document and we want to get the ID of this document which is generated automatically for us and also here we can just create our nodes and here we can just provide our timestamp and also we want to define the color foreign so here we have our knot and we have already defined everything which we want the user ID the title description time stamp and the color and also we have to define the document ID which is just the document ID which we have generated here okay now we can just use the notes reference again and for this time we want to call document and basically we have generated the document ID so you can just call here document ID and what we want to do is to set this document so this set function here is going to add the data if there is already an object or an existing document it's going to overwrite with this data and for this case here we can just call here notes which we have defined there and for that case we can just add the oncomplete listener and here basically we can just call this result and now we can just call here an oncomplete listener.invoke and we can just call here our result Dot is successfully so this one is going to tell us if our object is successfully completed so we can just easily invoke this function here okay now let's create here another function which is going to help us to delete the node okay now let's create here a function which is going to help us to delete node so you can just call this delete node and here basically we are just going to pass in the node ID and here we can just pass in the on complete function which is going to be executed when we finish up to okay now we can just call here our notes reference and here we basically pass in the node ID so we are going to grab the ID of this document and for this case here we want to delete so we can just call this delete function here and we want to call the on complete listener and for case here we can just call here our uncomplete and we can just pass in it it is successfully and for this case here we have completed to delete our object now let's create here another function which is going to help us to update the node okay so before you update here or not we have to add another parameters which we are going to update them so here we have obtained the node ID so we can just Define here another parameter so for example the title also the actual note we can just Define here the color and also here we have the on result so we can just and this one's just going to take up a Boolean and return a unit so here we can just easily update our knot so in order to update a note here so for example you can just create here notes reference and we have to obtain the document so we can just pass in here the note ID and we want to update the document so we can just call this update here so inside here we have to define the field value pairs so for example here if we want to update here the node ID and we can just easily update this node ID by using this so if you have so many values you cannot just Define this in a certain way because this is going to be tiresome so what you can just do here is create a hash map so we can just call this update data and we can just call this hashmap off and basically here we want to create a hash map of string and any so here we have to define the key value pairs so we can just Define here for example color and we can just easily call this two which we have defined there and also here we have a description and here we have to define a title and for this case here we can just pass in the update data and we can add here The uncomplete Listener and we can do the same on result here and we can just execute here our function and we call it it dot successfully okay so this is supposed to be a string so this is just the way which you can easily update a data using Firebase file store so you define here key value Pairs and then you define the object and then you can just easily use these not references and obtain the document and update the data so these are just all of the methods which are going to help us to perform our crude operations so now we can just deal with the view model and finish up our application okay so now let's create here a new package and we are going to create here a detailed screen so we can call this detail and inside here you're going to create a new cutting class or file and here we're just going to create our detail view model also you can create another cutting class or file and here we are just going to create our detail screen okay now let's start with our detailed view model okay now let's create here a Constructor and we want to obtain the value of our repository so you can create here private file and we want to obtain our Repository and here we can obtain the storage Repository okay also we want to create our data class for the UI so we can create here data class and we can call this detail UI state and here we can create a lot of variables so you can create here for example a color index and we can initialize this to zero you can create here a title we can Define here not now we can Define the statuses of the nodes so for example if the note is added and by default we can make this to be false and also you can Define the selected node and by default we can make this to be na and here we can Define our detail UI state and let's import these values here and this must be VAR not a Val okay now let's set the event to update our state and the first thing here we can Define on a color change now we can obtain our detailed UI State tagging and we want to copy this and change the color index to the color index provided and here we can obtain the Untitled change also we can use our detail UI State and modify the state again and also here we have to make this private set and here we can change this to on not change okay so now we want to define a function that is going to help us to add a node to our Firebase so first we have to provide yes several variables that are going to help us to perform this action now the first thing here we want to create a private variable and we can call this as user and this is just going to be a Boolean value now let's define here a get function and we want to get the we can use the Repository and ask if there is a user and for this case here we can check if the user has been logged in or not so that we can restrict the sending of data okay now also we have to obtain the user so we can create another private variable and call this user foreign user and can be nullable now also let's define here get function we can call our repository and we want to get the user okay so now let's define here our function okay now let's create here function and we can call this add not and let's check if has user so we know that the user is logged in now we want to allow the adding of the data so we can call here Repository and call add not and we can pass in here the user ID so we want to pass this user.id and to solve this we want to throw an exception if the user ID is going to be null and here we can pass in the title and we can use our detail UI State and obtain the title and we can pass in here the description and we can use our detail UI State again and we have to pass in the note and the timestamp is going to be defined also we want to Define here color and we can call here a detailed UI state and we have to pass in the color index and now we want to Define here the timestamp and we can use timestamp.now and here we have a callback which is going to give us the data and here now we can modify our UI state so you can call here detailed UI state and we have to pass in here the not added status and we can just easily pass using this it so this is just how we can easily add data to our Firebase file store okay so we want also when we open up our detail you our detail screen when we want to edit a knot so we want to create a function that is going to set up the fields so we can call this set edit and here basically we want to obtain a node so here we can call our detail UI state and we can change here the color index we can obtain here our not color index and here we can easily pass the description okay now let's define here another function that is going to fetch as a single document so we can create here a function and we want to call this get node and here we can specify a node ID okay now here we can use our Repository and we want to get our notes and here we can just pass in our node ID and here basically we can pass in the on error okay now here let's define our note ID so we can just change our UI state so we can call our detail UI state and we can deal with this selected node and here we can change to be or not and also here when we fetch this knot we want to reassign it to our set edit Fields so we can call here our detail UI state and this could be nullable so we have to wrap it with this it okay now here we want also to define a function that is going to help us to update our data so we can create here a function and we can call this update node and here basically we want to obtain the node ID and for that case here now we can use our Repository and we want now to update not and here now we can start to set our Fields so for example here title you can call our detail UI State the title and here in our node we can just call our detailed UI state and here we have to pass in our note ID and also here we have to pass in the color index and here also we have the result so we can just reset our detailed UI state and here we can set our update not status and we can just pass into be it here okay so we want here a function that is going to reset the update node statuses back to their normal state so we can just create here a function and we can just call this reset not added status and here we can just call here our detail UI state and here we can reset our not added status back to false and also our updated notes back to force and also you want to have a function that is going to reset the whole state back to its normal so we can call this reset state and here we can call our detail UI state and we can just create here a new UI State and for that case we are going to reset the whole state okay so now let's deal with our detail screen here so before we create this detail screen here we can create a new cutting class and we want to create a util class that is going to obtain our colors so here I'm going to paste a bunch of objects which are just going to be a list of colors which we are going to use them inside our detail screen okay now let's create here a new composable and we can call this detail screen okay now here we want to Define several parameters so here we have our detailed view model and this can be nullable and also here we want to obtain the not ID and also we want to obtain the on navigate okay now let's obtain here our detail US state so we can call here detailed UI State and we can use our detail view model and we want to obtain our detailed UI State and if this is nullable we want to return an an empty detailed UI state okay now here we want also to check if the forms are going to be empty or not so we can just create here a variable and we can call these forms also we want to obtain the selected color if we are just going to navigate here so you can just select this selected color and here we can provide an animation to change between color and here we can use our detail UI State and we want to select our color index and if not that is going to be the default color which is just going to be the color first okay now also let's obtain here the not ID and check if the Note 8 is going to be blank and we can check here our not ID that is not blank and for this case if the not ID is blank we know that we are going to add a new text field a new node and if not then we are going to update an existing node and for that case we can just easily use this so we can change here our icon so we can create here an icon and we can check if and if not here we can change another icon okay so we want also to fetch the knot if the knot is not going to be there then we are we are not going to fetch the knot so we can create here launch the effect and for the case here we can just pass in unit because we want to execute this block of code only once and for that case we can check if this knot is going to be then not ID is not going to be blank then we are going to fetch a note from firestore so we can call here our detail our detail view model and we want to get a knot and we can pass in here the not ID and if this is not the case then we want to reset our state so we can just call here a detailed view model and we can call here reset state because there could be the data inside our view model and they are not cleared so we want to reset the state to go back to our normal state okay also here we want to define a scope that we are going to be launching our creatine so we can call this scope okay also we want to obtain a scaffold stage so you can call this scaffold States and here we can call remember scaffold state so the scaffolding State here is going to help us to show the test or showing the snack bar so here we can just create our scaffold and the first thing here we can pass in the scaffold this state okay now here we can also add a floating action button and inside here we can provide an icon and here basically we can just Define the icon which we have provided there so if this is going to be updating then we can change the icon and also here we can just react to our own click so we know that the ID is there so you want to update so you can call here our detail view model and we want to update and basically here we can just pass in the not ID and if this is not the case then we know that we are going to add a new note so we can call here our detail view model and we want to add a not and this is just going to add a new note okay so here we can rename these padding values okay now here we're going to create a column and we want to pass in here a modifier here we can specify a background so that we can show a user when the color is going to change so here we can set the color and the color which we have selected there so we're going to call this selected color and this selected color has animation so there is there is going to be an animation between changing colors and also here we can just add padding and pass in the padding values which we obtain from our lazy okay so when we add a note or update not we want to notify the user that the note was added or was updated successfully so we can do this by using the snack bar so inside here we can just create an if statement and we want to call here a detailed UI State and we check the not added status if the note was added successfully now we can just use our scope and we want to launch a quality scope here and for now we can just call here our scaffold State and we want to call here show snack bar okay so when we show this snack bar we want to reset our state so we can call here a detail view model and we have to reset our state and we want to invoke the our navigation so you can call here our on navigate dot invoke so when we finish to add this we want also to navigate back to our home screen and for that case we are just going to navigate here also here we have to Define when we update our note we want to show another snack bar and for this case here we can just call scope.launch again and we can just use here our scaffold States and we want to use the snack bar and also we want to use this again here to reset our state and also to navigate back to our home screen okay so all of that out of the way so now we want to add this data here so as you can see here we have a place where we can easily pick colors so we can just easily add this by using a lazy low because we could have multiple numerous colors so we can just easily do this here and here we can just pass in a modifier and we want to pass into field Max width and here we want to space them evenly so across the space and also we want to pass in the content padding and we can use the padding values and here vertically we want this to be expressed by 16 DP and also here horizontally we want this to be spaced by 8 DB okay so we want to display here our item before we do this we have to create a color item which is going to obtain our object so now we can just come below this and create a new composable function and we can just call this color item okay so here we are going to obtain our color and we want to have the on click okay so here we are going to create a surface and basically here we can just pass in the color and we want this to be a circular shaped and we can just easily pass in here the modifier and we can make a padding of 80 DB and we can specify the size of this we want them to be 36 DP and we can just make this clickable and we can just invoke this the on click here also you can just easily pass in here border and we can use border stroke and we want to pass in here 2dp to be the width and also we want to make the color to be black so that we can identify all colors okay so this is just our color item now we can just navigate back here inside our lazy list okay now let's create here an items indexed so this one is going to obtain the item and also give us the index so we can just create here utils.colas and now here we have to rename this so we can just call this color index and also here we have our color okay now we can just call here our color item and we have to pass in here our color and inside here now we want to invoke our own color change so you can call here detail view model on color change and then we pass in here the color index which is going to be saved inside our state okay so now let's create here our edit text which is going to show us the place where you can add our title so we can create here an outline text field and here on the value side we can use our detail UI State and we want to pass in here to be our title and here now we can use our detail view model and we want to call the on title change and passing it here in order to modify our state and here we can just basically pass in a label and we can just use here a text and let's pass in here a modifier and we want to fill the max width and also we can provide here a padding of hdp okay so now let's create here our not edit text field so we can just create here outline text field and here now we can use again our detail UI State and here basically we want to use not okay so here we can just call our detail view model and we want to call the on not change and basically you can just pass in here it and also here we can provide the label and here basically you can just pass in a modifier so we have defined outside of our column this text field so we can just copy them and we want to Define them below the lazy column the less zero and here we want to Define our weight and we want to make this one f and also we want to provide here a padding of 8dp so we are providing here weight we want this outline text field to occupy the space which is going to be left by other items okay now let's write here a preview function that is going to help us to preview this and here we want to show system UI and here we can call our node theme and basically pass in our detail screen here and we can just pass in null here and here we want to pass in empty for our text field now let's try to preview what we have okay so everything is looking good here as you can see the UI is as expected so now let's finish up the other parts and hook up everything inside our application okay now so we can just close all other tabs and here we want to now to focus inside our home and here we can just create a new cutting class or file and here we want to create a home view model okay so now we can create here a data class and we can call this home UI state and here we want to display our notes list and this is going to use our resource object and here we can just name this resource.loading and also you want to get the node added not deleted status and this is just going to be a Boolean value and for the first time we are going to make it false okay now let's create here our home UI state and we can use a mutable State all and here we call our home UI state okay so now here we can just create our variables so the first thing we want to get the user and we can just call here Repository okay so also here we want to modify this user because we have defined inside here our storage repository this used as a variable so this variable is going to be initialized only once so we must make this to be a function and this is just going to be returning a user and also we can just come here inside our detail detail view model and we have to modify this okay so let's jump back inside here our user repository our home our home view model and for now here also we can Define another variable we can Define this as user and we can just call here repository.as user and here we can use our user ID and here we can just Define our get and we want to use the repository dot get user ID okay so now here we want to load our notes so we can create a function that is going to load nodes okay so now we want to check if the user is logged in so we can just load the data so we can call here has user and for this case here we can just create another function a private function that is going to help us to load this data and we can call this get user notes and here we have to obtain the user ID and now here we have to use a view motor scope and we want to launch this kuratine scope okay so now here we can use our repository and we want to get the user nodes and here basically we have to pass in the user ID and also we want to collect this and here now we can just modify our home UI States and here we can just provide our note list and basically now we can just easily obtain by using it here and now we can just easily call here our get user notes and here we have to provide the user ID so we can just pass in here our user ID and also here we have to check if the user ID is not blank and as this if this is the case here now we want to display an error that the user is not logged in so we can just call here a home UI state and here we can define a throwable and we can create here a new drawable and we can just write here a message okay now let's add another function here which is going to help us to delete the user node so we can just create here function and we want to call this delete node and here basically we have to obtain the node ID and here we can just call our repository and we want to call delete node and here basically we can just pass in the not ID and here we have a callback so we can just modify our home UI state and we can just modify here our deleted status and pass in it here okay so also here we have to add a function that is going to help us to sign out so we can just call this sign out and also here we can just use repository DOT sign out so we have not created this method which is going to help us to sign out so you can just navigate inside here our storage Repository and here we can just create a function that is going to help us to sign out and we can use our Firebase move but sign out and this is just going to sign us out and here we can just call sign out okay so now let's deal with our home screen here and finish to set it up okay now here let's pass in several parameters first so here we want to pass in our home view model and this could be nullable and also here we want to Define our or not click and here basically we are going to pass in the ID and this is going to return a unit and also we want to navigate to the detail page and here we want to navigate to the login page if the user clicks sign out and here we can just obtain our home UIC okay now let's create here little space first and here we're just going to create several variables so we want first to open the dialog so you can just call this open dialog and we can use a remember function and also here we want to obtain this selected node so we can just call this selected node and this can be nullable so we are going to use also a remember function again and we are going to use a mutable state of null also we can create here a scope so we want to launch our quarantine so we can just call this scope and we call remember correlating scope and also here we want to obtain the scaffolding state and call remember scaffold this state okay now here let's create a scaffold and we can pass in here this coupled state okay now let's add here a floating action button and here we can just pass in the icon and we want just to pass in using these icons here and you can use a default and also here we want to react to the on click and we want to navigate to The Details page when this Floating Action button is going to be clicked so navigate to a detail page and we can just invoke this function here okay now let's add here a top bar and here we can basically add a top up bar and here we can just pass in the navigation icon and you can pass in here the title okay so here in the navigation icon we want to display an icon button and here you can just use the icons okay so here we're going to use this exit to app and here they on click we want to sign out so you can use our home view model and we want to navigate to the login page so we can call here navigate to login page and invoke this and here on the part of the title we can just pass in a text okay so here we can just pass in the padding okay so now we can create here a column and we can basically pass in here a modifier okay so you want to use here when statement because we're going to receive the list so we can use here our home UI state okay so now we want to check here if this is going to be is loading and if this is the case then we want to show a secular progress bar and here basically we can just pass in a modifier and we want to fill the max size and we want to call here wrap content size and then we want to align this to the center so we are filling up here the whole size so we don't want this to follow the column principles so we are going to make it to Center its horizontally and vertically and now here we can check if is resource success and here we can just add an else Blanche and we can use here a home UI state and we want to obtain the not least and we can pass in here the color and we can make this to be red okay now let's deal here with this access part okay so now here we want to display the notes inside a an item so you can just come below this and we can create another composable and here we want to call this not item and here now we can just pass in notes and we want to pass in the on Long click so we want to delete an item when we perform a long click and also we have the on click which is going to help us to navigate when we click a note item and here we can just create a card and pass in a modifier and we can just create here modifier and we want to use combined click here and we can just call here the on click and we want to use the online click and we have to invoke this function also and we have to add in the experimental API here and here we can just add a padding of 80 DP and we can set the background color of this so we can just use utils and now we want to use the selected color so we can just use here our note and we can use our color index to get a selected color okay now let's create here a column and we want to display here a text and we can just use here our notes and we want to select here our title and also here we want to provide a style and we can just use here material theme and we want to use header six because this is just going to be a title and we want to change also the font weight and we want to make this to be bold and we want to make this to occupy a max line and only to occupy one line and in case if there are overflows so we want to clip and also here we can just pass in a modifier and we want to pass in a padding of 4dp and now let's create here espresso and we want to specify a special 4dp and now here we want to create another text but we want to decrease its opacity so we can just use the compositional local provider and here basically now we can just use the local content Alpha and this is just going to give us the we want to decrease the opacity so we can just use this content Alpha now let's keep this in a new line and we want to use this disabled because it's going to decrease the opacity giving us a gray effect and for this case here now we can just create our text and here basically we can just provide our style now we want to provide a material theme and we can just use here body one and you can put this in a new line and here we want to define the Overflow and here we want to Define text ellipse and we can Define here modifier padding of 4dp and we want to define the max line and here we can just provide all four lines so we don't want more than four lines here and here we can just add another spacer for DP okay so also again we want to copy this and instead here we want to create a debt and we can just easily change here the alignment and we want to align this to the end so we can just add here an align and we want to make the alignment dot end okay so here we want to create another function that is going to help us to format the date so let's create here a private function and we want to call this format that and here we want to receive the timestamp and this is just going to return a screen and here we can just create a simple date format and here we want to use this format here and here we can just use local.get default and for this case here now we want to return and we can call here our timestamp.to date so that we can just format this and now let's just navigate back inside our card and here we can just call format date and here now we use our node and we obtain our timestamp and for this case here I think we have finished to create our UI so now let's create here below this a preview function and here we can just call our home and here we can basically pass in now okay so now let's finish up to set our UI so you can just navigate here back to our own success item okay so let's create here a lazy vertical grid and here now we can just provide these cells so we can just call this grid cells and we want to use this fixed and here we are just going to define the amount of what we want and this is just the experimental because I'm using a lower version of compose but it is just in a stable mode and here we want to pass in the content padding so here we can just pass in the padding values and we want a Content padding of 16 DP we have to use here the items which has a list here and here we can just Define our notes okay now let's define our note item okay so now we want to react when we perform the on Long click and what we want to do here we can just invoke here so we want to open the dialog so we can just set up here open dialog and we can make this to be true and also you want to get the selected note and you can just pass in here the knot so we are going to create this dialog in a moment so for now let's also invoke here the or not click and we can just pass in the ID here so you can just use here the note and we want to pass in the document ID which is just going to be the not ID okay so I think now we have finished to set up a UI so we want to check if the user is actually logged in and if not we want them to be navigated to the login page so now we can just collapse everything here and now below this we can just create here a launch the effect and here now we can just use our home view model and we want to check if has user so you can just check here we can use here the home view model and we want to check if has user and is actually false so if this is actually false then we know that the user is not logged in so what we can do here we can just call here our our nav to login page and we want to invoke it here okay so now here we have finished to create our home UI so let's navigate here inside our navigation and now we can just finish up and hook everything up okay so right now here we are just using a single navigation graph and as you can see here we have a lot of composables and we cannot just Nest them inside here so we are going to use a nested navigation which is just easy to implement and for now here we can just delete this and what we want to do here is to add another enumclass and here we are just going to call this nested navigation nested routes and here now we have our home which is going to be our main we have our login route here sorry okay so now we can just easily copy everything here inside our Authentication and we can just create here an extension function and we want to use here the enough graph Builder and we want to call this out graph and here we want to pass in the nav controller and also you want to pass in here the login view model and now we can just pass in this now we have first two call here the navigation so here we have to specify the stack destination so we can just specify here our start destination and here basically now we can just using our login and we want to use this sign in n.9 and we have to specify here the route so this is just going to Define these routes of this navigation graph and here now we can just use our nested and routes and for that case here now we have the navigation Builder here so we can just use here our composables which we have been defining here okay so instead of navigating directly to the Home Route so we can just use here the nested navigation so we can just call here the nested routes and we want to use the main.net so this one is going to define the Home Route and the detail route so directly we are just going to navigate to this route here and also we can just copy this and also you want to use it when we are going to so also here inside our sign up route we want to change this to navigate to this route here okay now we can just jump inside here our nav host and for now here we can just call here our out graph and we want to pass in here the nav controller and the login view model and for now let's create here another extension function so we can just call here enough graph build again and we want to call this home graph so here we want to pass in the nav controller and also you want to pass in here the detail view model and also the home View mode okay so here we can just Define our navigation and this is just going to define the start destination and for case here inside this home route we want to have our first destination which is just going to be the home so we can just call here the home routes so this is just going to be our start destination and we can just Define the route and here we have to use the nested routes and we want to use this main.net so whenever we navigate to this route here the starter destination is going to be the home page and for that case here inside we can just add the composables so we can just create here a composable and we want to define the route here and this is just going to be our home route okay now let's define here a home composable okay and here we want to Define our home view model and inside here they are not click we want to define the not ID okay so here we want to navigate to the details clean but we are going to have to pass the note ID so we can just create here enough controller and we want to navigate to the details screen so we are just going to create here our detail screen composable right now here but first we want to navigate this so we can just use here the home routes and in order to pass the ID here we are just going to pass in a parameter so this is just how jpa compose navigation works so here we can just pass in the parameter which we want which is just going to be the ID and again here we are just going to call this node ID and we want to call here launch single top and make this to be true so we don't have we don't want to have multiple instances of this launching so we don't only want a single item to be there okay and here we want to navigate to the detail page and for now here we can just call here enough controller and we can call just navigate and here we want to pass in the home route so as you can see here we are using an optional argument passing here because we are just for example here when we are going to click The Floating Action button we don't have the ID so we are just passing in here the the route and instead here we are passing the route and the ID okay so here we want to click when we want to navigate back to the login page so the user is either clicking the sign out button so we have to navigate back to our login page so we can just call here there are enough controller and we want to navigate so we can just use here our nested routes and we want to directly go to our login page and the login page knows what it can do and here basically now when we navigate we want to launch a single top and we can make this to be true and we want to pop up too so we don't want to include anything so we're just passing here zero so everything in the back stack is going to be removed and we want to make this inclusive including this screen here so we are just going to remove and for that case I think we have finished to create here our navigation inside our okay now let's create here a detail composable so we can just call this composable so here we want to pass in the route so we can just call here our route and here we will have to specify the template and for our template here we want to pass in the ID and you have to specify as how I'm writing here otherwise we're just going to get an error when you are navigating and we have to pass in here the arguments parameter and here we can just use a list of and we want to use the nav arguments and here we have to specify the name and for the case here we have already specified the name of the ID and this is just going to be here the same name okay so here we have now our parameter so we can just Define here A type and for case this is just going to be a string type and we want to define the default value and for the case here we want to define a default value of an empty string so as you can see here we are just using this optional argument because sometimes we don't have to pass in the argument so we have to define the default value which is just going to be an empty string for that case okay now here we can just open up our brackets and here we have to rename this to entry okay now we can just call here our detail screen and here basically we can just pass in our detail view model and the a the ID here we can just easily obtain it from the entry and we want to get the string and here we can just pass in the ID and we want this to be as a string okay so we want when this back button is going to be clicked so you want to navigate back to where we were so we can just call this navcontroller.navigate app and this one is going to help us to navigate back to where we were okay now I think we have finished to create here our home graph so we can just navigate back here inside our nav host and we can just pass in here our our home graph and here we have to pass in the nav controller and we have to pass in here the detail view model in the home view model so we can just create a detailed view model and home view model and for this case here now we can just pass in here our detail view model and the home view model okay so as you can see here now our nav host is looking pretty good and this is just a good use of nested navigation so now let's jump inside here our main activity and finish up everything okay now here we want to obtain other view models so we can just Define here the home view model and instead here we can just call our home view model and here we want to get the detail view model and here we can just call detail view model and for that case here we can just pass in our detail so I think everything is looking good now let's try to run our application and see the changes we have made okay so when we launch our application we are getting this error here we cannot create an instance of the home view model so let's jump inside here home view model and as you can see here we are instantiating here the repository but we are not going to initialize it so here we have to initialize our home our storage Repository and also we can just jump inside here our detailed view model and check it also here we are not instantiating this so we can just call this detail we have to call here the storage Repository and now let's try to rerun again and see the changes also we are getting another error here that navigation destination sign in is not a direct child of this enough graph so if you navigate here inside our navigation so you can just come here inside our stack destination we are just defining here the login route sign in to be the starting destination so for a case here we can just Define the start destination by using these nested routes which we have defined here so we can just change this and we want to use here the nested routes and we want to use this main.name here instead of using the sign in as our destination now let's try to rerun again and see okay so our application has launched successfully whoever we are having here a spinning bar and also when we navigate here we can just easily type in our data and we can just change here our colors as usual and here we are just having a update icon and we want this to be a check mark because we're just creating this and we're going to fix this right now here and when we navigate back here we are still getting a spinning bar and this is just because we forgot to actually Implement a method that is going to fetch the data to the server so we can just jump inside here our home and we want to create here a launch the effect and here we are going to pass in unit because we want to execute this block of code only once and for now here we can just call here our home view model and we want to actually load the notes and then we can just jump directly to our details screen here so you can just find it here the detail screen and we want to fix this so when we navigate here in the icons we want to change here is not the form so we want to change this is not when the not ID is going to be blank we are going to have a check mark and if not then we are going to have the update icon and for that case we're going to fix this issue and also we want to hide this Floating Action button if the user is actually not typing anything inside our edit text so we can add here an animated visibility and directly here now we can just check is forms not blank and then we can just paste this and here we want to add this to opt in for experimental apis and now when we run our application we are going to get an error because we want to also include an a compound query so let's try to run our application and see okay so when you run the application and navigate to The Log cut here you can see we're getting this message here so the query requires an index so we are required to create a compound query because we are having two fields which we are editing and here we can just click this link here and we can easily create this okay so the console has detected the fields which we want to create a compound query for so for now we can just click this create index here and it's going to build this and as you can see here it's just building okay so now our query is enabled so we can just jump inside our application and now start to see how we can add and remove data okay so now we're just getting here loading animation and now we can try here first to log out and you can just try to sign in or create a new account so you can just try here ABD at gmail and we can just sign in here and we have a successful login here now let's try here to create a new item and as you can see here our Floating Action button is hidden and for now here we can just create our title one two three and right here our notes one two three now let's try to change here color and now let's try to save here our item and we have the added not successfully and we can just navigate to the home screen and here we have our title and now let's try to click this and we want to to edit this color here and also change this and now let's try to update our item and our note is updated successfully and then we can be navigated back to our home screen now let's try to add another item here and now when we long click here we're just going to delete a note and we get this now we have deleted the not successfully so guys let's end up here so if you have any question please let me know in the comment section below and if you find this video helpful please don't forget to provide a like And subscribe for more videos so see you in the next video bye bye for now
Info
Channel: HoodLab
Views: 5,416
Rating: undefined out of 5
Keywords: firebase, firebase tutorial, firebase auth, firebase developers, firebase developer, jetpack compose, jetpack compose tutorial, jetpack compose firebase
Id: jDs8Mc3Qz7k
Channel Id: undefined
Length: 146min 36sec (8796 seconds)
Published: Wed Sep 28 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.