Flutter Firebase & DDD Course [8] - Sign-In Form UI

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
it's finally time to create the user interface which will allow our users to sign in this will come with everything necessary including displaying the validation error messages coming from the value objects hello welcome to resew core where you're getting prepared for real app development so that you will get freelance clients or a job and be confident about apps you've built so subscribe and hit the bell to join us on our quest for becoming in demand flutter developers in this 8th part already of the domain driven design series in flutter we are going to build out this precise user interface we're now going to write much logic in this part because everything has been written previously we are just going to communicate with our sign-in form block and the end result will be that when we forget to input some valid data into the fields we sign in we are going to be shown invalid email error message and short password error message but as soon as the email is valid so valid com you can see that the error message goes away and the same goes for password when it's at least 6 characters long let's start off inside main dot dart because actually we have not yet built any kind of a UI and all widget code we have in our app currently is this my app widget and to be honest I would not keep any UI related stuff inside main that dart usually mean that dart should be reserved only for some setup like for example configure injection and then run app or for example you may set up your crashlytics code or some other similar service here but otherwise widgets are actually a part of the presentation layer so we are going to create our root widget which is going to hold the material app also in the presentation layer so let's do just that we're going to create a new folder under presentation and let's call it four and inside of it we are going to have an app widget dot art and let's just copy or actually cut out this my app widget from main we're going to go over to the app widget file paste it there and let's just rename it to app widget and let's also import material dot dart like this and now we're going to go back to main the dart and we're just going to say run app app widget with this done we can see that the widget which we currently have here definitely doesn't hold any sort of a UI which looks like this so let's change that basically we want to have a sign-in form with two fields and then three buttons sign-in register and sign with Google but first let's run this app on an emulator to see how this one actually looks like right now of course it's not going to look fabulous so here we go we have the default material app so let's add the UI which we should have in there which are the text fields for the form and also the buttons we can see that we have a scaffold widget set as the home parameter of the material app but actually we're now going to write our page right inside of app widget where instead go into the libous skelos and instead of this we are going to create our page inside a very specific feature of the presentation layer which is going to be inside a new folder called sign-in now inside this sign and folder we are going to create a sign-in page the dart and inside of there which is going to have a very simple sign-in page so state less widget let's import material also and it will hold only a scaffold which will have an ad bar and this will hold title let's say Const text sign-in let's see how that looks like once we assign this sign-in page to be the home of our app widget and just like that we can now check out our emulator and sure enough we have the sign-in text right up there now comes the time to build out the form UI and sure we could build it out right inside our Sun and page like the body of it but instead of building out directly in here we are instead going to create a special widget for holding the form UI we're going to create it under a new folder under sign-in a feature is going to be called widgets so now we are located under presentation sign and widgets and inside of there we are going to create sign-in form that dart and just like that we are going to also create a stateless widget sign-in form and I know we are going to be operating with the form and we are inside a stateless widget but this is entirely possible because we are going to use our sign-in form block for the logic currently our styling form does not contain any meaningful user interface but let's immediately put it as the body of our sign-in page and actually can we just put it like this just simply body will be sign-in form well I would say no why is that well you have to realize that we have a sign-in form block in the application layer right here this one and we want to provide this down the widget tree and we want to get it to be available inside a sign-in form so we need to use a block provider over here so let's wrap this with a widget it will be block provider let's import block or floor block that Dart and like this we are going to also set the create parameter and we're going to say with that we should instantiate the sign-in form block like this actually not like this because this would instantiate like manually and we would need to pass in the correct I off facade into that block and instantiation into the constructor and that's precisely why we have actually setup dependency injection in the previous parts using gedit so in order to get our instance of sign-in form block which will be set up properly we're going to instead call get it with the type parameter sign-in form block and just like this we are good to go after we import the injection that dart file well we have where we have set up this get it field top level alright so the UI still looks the same so let's actually change it right I can open up the already finished app which you can by the way see the code for on github and also on github from the link in the video description you can find the code for this episode and when we sign in with Google here what's pretty important is that when some issue happens like for example we closed down the pop up we are going to get a canceled snack bar from the bottom with block this is possible with a block listener and building the UI is possible with block builder widget and because we want to both build the UI and also show something in response to state changes coming from the block instead of using block listener and block builder separately we are going to use block consumer and this block consumer will consume a block of type sign for block and the state which it will consume is sign-in form state and now we're going to set up the listener which will accept context and state and also we're going to add the Builder which will also accept context and state and this one should also return some sort of a widget so let's first worry about the UI we're going to return form and it will hold a child and since we want to display multiple inputs it's going to be a ListView let's also add the semicolon at the end and this ListView will hold multiple children and these children are going to be as follows in the top-most widget we actually want to display our very cool emoji to tell users that we are inside a note-taking app so it will be constant xed and it will hold the emoji for the notes so I don't yeah this is how you can find it on mag just type in notes and you're gonna be good to go and we also need to style it most likely because now it looks like this you cannot even see it properly it's so much hidden in the corner and so small so we are going to make this text style to be textile and we're going to set the font size to be 130 now it's going to start to look good and also we are going to Center it so let's just say text a line is going to be Center so text align Center and with that we can see that it's nicely shown on our screen and it's probably going to be better if you are gonna be able to see the screen at all times so here we go we have the emulator on the right side the next thing we surely want to have here is a text form field for entering the email so let's just create it and see how it looks like right now well it doesn't look any good but let's just continue we're going to also set this text form fields decoration because we want to display the email label inside of it so let's set it to be input decoration and we're going to say prefix icon is going to be icon icons that email okay say that possibly format it we can see that the email icon is added over there but it's still pretty bad looking so we are going to say label text and it's going to be email and of course you would probably use some translation here some localization now what's pretty important for an email field is to set autocorrect to be false because email should of course now be auto corrected with your keyboard and this parameter will tell the native operating system or the browser or whatever comes next as the flatter platform to possibly ignore any auto correction suggestions from your keyboard of course we are currently not communicating with the Sun in form block in any way but before we do any of that let's first duplicate this widget down so we're going to have an error text form field this one will be for password and icon will be also something different so lock and once we say that we can see how it looks like and also we can actually make these input decorations to be constant like this in addition to autocorrect being false for the password field we are also going to probably want to obscure the text so let's say obscure text true and once we save that the text will be just dots let's face it though this UI does not look at all like the one you've seen at the beginning of this part it's not green but instead it's blue and it has these lines instead of looking like this for the input fields so let's change that right now we're going to set up a theme inside the app widget dot dart file everything that's possible with a theme is also possible by styling individual widgets or also we can create some global styles inside a static feel inside some class and you can assign it like that but if you can use a theme you should probably use a theme because it makes everything so much simpler and also supports dynamic changes of theme to for example light mode and dark mode first though let's change the title of our material app which seems to be incorrect so we're going to set it to notes and now let's just say theme and we're going to set it to theme data that light and we're going to copy it with some changes these changes are going to be that the primary color should be colors that green 800 it's going to immediately change the look of our app accent color has just set it to be colors that blue accent I think the default one is light blue if I'm not mistaken it doesn't really matter this accent color is not going to be used that much the last thing we're going to add into this theme in this part is the input decoration theme we're going to set it to input decoration theme and we're going to set up border should be equal to outline input border because default is under line input border but we want to have an outline so outline input border and we're going to say that border radius should be equal to border radius that's circular and the radius will be 8 so once we format this it's gonna look really nice of course it's done looking very nice right now because we don't have any spacing in between the text form field so let's change that immediately but actually before we do that we are running inside debug mode right now because we are debugging the app after all but we don't want to see this debug banner and top corner so let's just say debug show checked mode banner to be false and now it's hidden so now let's go over to the sign and form widget and we are going to add some spacing in between these cramped text form fields so we're going to add right after the first text which shows the note emoji we're going to add Const size box and let's say height will be 8 pixels logical pixels actually and let's just copy this and we're going to paste that between the text form fields so again Const size box and because it's a constant we are now going to create two instances of the same widget with the same height parameter passed in instead we are going to reuse the same instance so our app will therefore be a little more performant it would be without this constant optimization so if you'd like to learn more about constants as I've said already a few times probably you can check out the video from the cart in the corner now comes the time for the buttons so we want to have them arranged in this manner so sign and register are inside one row and then below them is sign-in with Google button this tells us a lot about which widgets we are going to use for their layout so we want to have a row for the top two buttons and it's children are going to be flat buttons because they don't have any actual background themselves so flat button comes here and its child will be Const text sign-in in all caps oops sign in and let's also set the undressed which is required so that we won't have any errors so here we go we have the sign-in button let's now just copy it in a way and this will be the register button but they are not looking anywhere as good as they should be they are pushed in to the left and they don't expand to the fall with which the row should give them so what are we going to do well we are just going to put them in to expand it widgets so let's wrap it with a widget expand it and an expanded widget has the beautiful property of of course expanding to the biggest available dimension so in the case of row its width in the case of column its height and it's another beautiful property is that if you have multiple expand widgets they are going to divide the space in between them equally because currently this register button is fixed with widget it just has the size that the text has but now when we wrap it inside expanded too it's not going to be a fixed width widget is instead going to be dynamically sized with it if you want and it's going to divide the sizes equally between these two buttons this is looking great let's also put the size box again in between the row and the text form feel for the password and the sign-in with Google button will be erased button and it will have set up on the rest of course currently we're not going to do anything inside of there and we're just going to say color is equal to colors that light blue and its child will be text so again Const text we're going to say sign-in with Google and we're also going to style it in some way because currently it's just black that we want it to be white to contrast with the background color so its style will be text style and we're going to set up the color to be colors white and once we save that it's going to look great maybe we should also set the font weight to be bold if that makes a difference yes it does a bit so we're going to leave it at that let's now connect it with the sign-in form block so we are going to go over to our form and the first step we need to make is to set Auto validate to be equal to state dots show error messages this is coming from the block and from the block consumer respectively this will allow for the immediate validation of the input as soon as one character changes is going to be validated and possibly an error message will be shown below the text form field but only when we allow it to and this is precisely what this show error messages state field is responsible for if you remember a few episodes back I explained it in depth now let's come over to the text form fields so we need to set up there on changed callbacks which are going to be passed in a value and in turn we want to get this value over to the sign form block so we're going to say context use the new block extensions so block of type sign-in form block and we're going to say add and we want to add an event sign-in form event that's email change and passing the value as the email string and what's going to happen inside the block is that this value will be validated inside our value object it's surely nice that we are able to keep the value valid at all times with the help of our value objects right here for example the email of value object present inside the valiant objects that dart under the earth feature inside the domain layer right we're doing something like this and it's all nice but this will not simply communicate it's validation value over to the UI just like that we need to tell you I how to obtain the result of the either type that means we're or not the value is actually ballot for it every text form field has a validator which is usually passed in a value but we can ignore that because we already have the value and also the validation done inside the block and where is the validation value located well we can say state dots email address which is our email address value object and now we could technically say value which is the either type and say that actually or not it's not going to get formatted whatever and say fold now it could get formatted a bit this formatting is really horrible but hey this is what dart has to offer to us unfortunately oh now we're looking sharp and when the value is on the left side so it means it's a failure we are going to say F so failure map and with map we would need to handle every possible failure case so in the case of our authentication failure or this value failure actually we have two possible failures which is invalid email and short password but imagine you have more of them we only want to care about invalid email here and show something like invalid email string in the case of short password we would probably want to show nothing so something like no would be returned from here the problem is that when you have more failures this starts to get clunky and that's precisely why we are instead going to employ the maybe map function maybe map and now we just need to provide or else which will be run on every other failure which is not an invalid email oh and of course we also need to pass here the value the string which is held inside the invalid email okay hopefully it's going to get formatted no we're gonna need to help it a bit so let's do just that awesome and now we are good to go and in the case that everything is correct we just get the right value we are going to return null as it is now we can actually ignore this right value the problem with this approach where we get the state from our builder is that this state will be always one character older than the last value which was inputted into the block so let's demonstrate if we say something like a B and now we input C what's going to happen that this unchanged has run with ABC being the value but the validator has run immediately after unchanged the problem is that this state from the block did not yet have the chance to process this event so the state of the block validated only a B not a B C C is missing that's because the UI did not have yet the chance to rebuild this builder with the latest value of the block what we can do to mitigate this issue is to not use the state coming from the Builder which has not yet been updated but instead use the state coming from the block directly when we get it using provider so I'll just say context block state like this so we are still getting out of the Sun informed state but through a different way or basically getting it directly from the block and not from the Builder and this will actually work let's do copy these two methods so unchanged and validator and we're just going to paste them into the password field and something always goes wrong when I just copy and paste stuff like this but we're going to give it a try the Sun inform event which would be triggered as pass worth changed we should say short password and we should also trigger this on short passport failure we should not get hold of email address but instead of pass word and the formatting will go to hell that's not nice I think these are all the changes that are needed so now we just need to connect the buttons to trigger events to the sign-in button and pressed should say context that block of type sign-in form block dot add and what do we want to add here well we want to add Const sign-in form event and let's say not email changed of course but instead sign in with email and password pressed like this awesome and now we're going to copy this unpressed and we're going to paste it into the flat button below which is for registering we're just going to say register with email and password pressed alright and lastly we have this button for sign-in with Google so again I'm pressed will have a very similar thing in there but instead of calling sign with email and password press we're going to say sign in with Google pressed and again if this seems a bit messy it's because it is and you are gonna be able to find this code in and github so we should now be able to sign in if I press this we're going to get invalid email and short password I actually hope we are in the correct app we probably are if I had restart we should see that the UI gets reset yep it does so that's cool so now we input some invalid data sign an invalid email now we say add G dot C and immediately this is a valid email with a Val domain so the error message goes kawaii I delete see our message comes back and the same goes for password so 1 2 3 4 5 as long or as soon as it's 6 we have 6 characters and the error has gone away so that's cool we can sign in we can register it's going to all work but I'm actually not even going to demonstrate that because you know we actually don't have any proof that sign-in work because we cannot see it navigate to any other page and use the firestore because we have not said anything like that up we just have this one screen for signing in but what's more interesting than sign-in with email and password is signing in with Google so it works but when we dismiss it before you could see that we have gotten this snack bar from the bottom now we are just going to get an exception but that's not an issue this just happens because we catch all uncaught exceptions for some reason it also catches the ones which are actually caught but hey I mean this is crazy this is something which bugs me all the time but anyway you see that the app actually did not crash it's just this stupid vs cold which catches everything or the flutter as decay probably but what we want to do when something like this happens is to show that snack bar at the bottom and that's precisely what we have this listener for at the block consumer at the top here we want to get hold of states that odd failure or success option and we want to fold it if it's none so the left side here we're now going to do anything but if it's some this means it contains either and this either is of type of failure or unit so we want to say that again if either that fold if it's failure then we are going to create a snack bar but if it's all good we have the right value so no errors present we are actually gonna want to navigate to another page to the home page but we are going to handle that in a different part for now let's focus on the snack bar we could just use the default snack bar but that's pretty clunky and we want to get something done quickly and that's why we're actually going to use a library for snack bars which is called flush bar while we are inside this pup spec that IMO file we can see that we have a lot of dependencies which are out of date so let's just do a brief maintenance update darts block to 4.0 0.0 firebase score is fine Google sign-in is outdated to get it also yeah priest everything is how they did injectable generator outdated horrible and now what we want to do is add dependency with puck spec assist we're going to save flash bar it's gonna be added here currently one point ten point out and once we save that we're gonna be able to use that from our sign-in form whenever we have a failure here we are gonna want to say flush of our helper flash bar with the lowercase B helper actually whoops and now we want to create error and the message for the error will actually come depending on what the failure is so we have an odd failure here we want to map it and we have a lot of cases here so let's select them all with command or control D like this we're going to set them to be functions which are going to have ignored input parameters like this they're all going to return string which will be empty for now I know you cannot see Jack here but that's fine we're going to get over it and we're expecting semicolon all right the formatting has just gone completely crazy and now we got some sort of an error but we are probably just going to ignore it this error we are going to focus on these failures and creating snack bars out of them actually I'm just going to copy and paste the already created strings so whenever it's cancelled by user we are going to display cancel whenever it's server error we're going to display server error and so on and also we mustn't forget to show the snag bar and again we get some sort of an error here email address was called on no this is interesting why is that happening it seems as if the state of the block was no I think this happens only because we need to Hart restart the app I don't think this is an actual problem because this has never occurred before and it doesn't make sense because the state is never know if anything is just initial at the beginning it's not null at all but anyway now we can still input our data here register it's invalid so that's nice we get the error messages and also when some error happens and the most easily replicable one is when we cancel Google sign-in actually I'm going to uncheck to catch uncaught exceptions so that we want to get crash and sign in with Google now we're going to close that yay you can see that we get the canceled snack bar and that's of course coming from no place other than our a listener all right I know that this might have been a bit too much at least this last part with these formatting of parameters yeah it's really something you cannot see anything on the screen but anyway we got it done we got the UI working and in the next part we are going to progress even more to actually be able to get the already signed in user from firebase off and then also we are going to decide if after launching the app we should show the Sign In screen when the user is not yet signed in or if we should show the notes when the user is of course already signed in so if you haven't already made sure to subscribe to this channel if you don't want to miss that next part and also more tutorials like this and also join the notification squad by hitting the Bell button to make sure you grow your flower skills because here our reso coder I am determined to provide you with the best tutorials and resources so that you will become an in-demand clutter developer and if you are serious while becoming a great fall developer also can build real apps for clients or at a job go to flutter that education link is also in the video description to get the top curated flower news and resources aimed at improving your app development career over there you can also subscribe to my mailing list to get the best for resources delivered weekly right into your inbox so if you like this video give it a like and also share it with our developers who are going to then learn how to build this nice UI in domain-driven design style because as you could see we are not doing any validation whatsoever inside the presentation layer instead everything is coming from the value objects which are present in the domain layer leave a comment if you have anything to say see you in the next [Music]
Info
Channel: Reso Coder
Views: 15,533
Rating: undefined out of 5
Keywords: resocoder, tutorial, programming, code, programming tutorial, flutter, flutter tutorial, flutter firebase, flutter firestore, flutter firebase auth, flutter firestore tutorial, flutter firebase tutorial, flutter architecture, flutter architecture patterns, flutter domain driven design, flutter ddd, flutter database, flutter todo app, flutter todo app tutorial, flutter todo app firebase, flutter app tutorial, flutter app example, flutter clean architecture, flutter bloc
Id: KfuUkq2cLZU
Channel Id: undefined
Length: 42min 37sec (2557 seconds)
Published: Tue May 05 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.