Flutter Provider Package In Depth - StreamProvider

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hi folks welcome back to channel we've got a little bit of a storm brewing here in old New England but that's alright work we're used to that so we're gonna cover stream provider in this video the last video we covered change notifier provider and if you miss that you're just here for streams that's fine I'm gonna put a github repo down below you can click that get up to speed but basically we're doing this through an app just so it has some some real world relevance and it's it's a Nordic ski app so you can go into this app and see what everybody else is using for waxes at the Nordic Ski Area you can set whether you're using Imperial or metric standard units and which brands of wax you want to see so kind of a useless app except for us helps us in this situation and we use change notify our provider for the settings and now we're going to use stream provider for the reports coming in in the app firebase is going to be used so we'll devote a little bit of this video to setting that up I only use stream provider in here as I was doing it I could see possibilities for working in blocks integrating the different providers but I didn't want to make it too complex so there's definitely some future video material here and how to use stream provider in a I think an even more efficient way but this video is gonna focus just on the stream provider I'm gonna get in off the lake we'll go in warm up have a cup of coffee and we'll get started [Music] all right so if you did the change notify air provider video or you got to get hub repo this is our starter app not a whole lot going on here in the main page there is a settings page which you can get to by clicking this gear and in here we could set the units from Imperial to metric we can also select the wax lines which are the brands that that make wax wicks toko and the idea is we'll have a streaming list of reports coming in from the ski area on the main page and that will be filtered by the values of our settings so we'll only see Swick's or toko if we want to see one or the other you can select neither if you don't understand the point of the app or you can get both and then we'll have a temperature reading on the main page and we will convert that to imperial units or metric units depending on what the user has selected all right so that's the objective we are gonna need a fire base project so if we go to firebase google.com if you don't have an account you'll need to sign up and if you do you will be given the option of adding a project now I do have a project set up here for the source code so I'm gonna add another one and I'm just gonna call it wax no I'm not cuz I need at least four characters alright so we'll call it wax - but you can call whatever you want I don't I don't need Google Analytics so we're gonna disable that part and we'll just go ahead and create the project I will pause you don't have to watch this create a firebase project for me alright so it is finished I'll click continue and what we need here is we need a database and we're gonna create a fire stored data base so we'll create database I'm gonna start it in test mode that way we don't have to mess with permissions everything will be open you can select your region if you don't like it and click done and that's gonna need some time too so I'll pause it again all right there we go we have a blank fire store database exactly what we want and so now let's go ahead and set up an android project so we come to project overview and we want to add an app so we can click on Android I'm just gonna add android for the purposes of this video if you want to add iOS you can do that as well all right we need a package name and we can get that from our code so if we go to Android we expand Android we go into app we go into the build dot Gradle that's in there about halfway down we will come to application ID and that's what we want so I'll copy that I'll paste that in there and then we can give it a nickname I'm just gonna call it whacks app Android and I'm not gonna add a signing certificate because we're not going to use any of these features yet so we'll go ahead and click register app alright that will give us a Google services JSON which we can download and I had one already in my download folder so I'm gonna have to rename it it should not have this one affixed to it there we go and so I'm gonna drag that and I'm gonna put that right in this app folder and so it should sit right below build that Gradle right there so we got that step so we click Next and so we want to do a little bit of adjustment to our build.gradle files let me get this situated so we can see both alright so first of all on the project level build that Gradle so that one is out here right here outside of this app folder this one and we want to check and see that we've got Google and the repositories which we do want to make sure we have a class path in dependencies for comm google.de MS Google services which we do not so let's copy that and right after the Kotlin plug-in I'm going to paste that in and then we at lastly we want to check in the all projects that in our repositories we have Google which we do so we're all set with that one now we want to go to the app level build which is the one in the app folder which we just had open to check the app ID we want to apply this plug-in right here this GMs Google services and we want to add it right after the com Android application right there I am also going to change the minimum SDK to 21 there are there different instructions out there for adding firebase to your project if you go to firebase there's a different instructions than they actually lead you through here from adding flutter I wish they would get that more consistent but one of them does include bumping that minimum SDK version up to 21 it's not here but I've had luck with it so I'm just gonna go ahead and do that alright we'll click Next and we are done there so now we can go to I'm gonna stop the emulator because we do need to add the package we need to get the cloud firestore package from pub dev so we can go to pub dev we can search fire store we should get this cloud underscore fire store that's the official package and we go to installing and we can grab this and we can put that our pub spec yeah Mille all right a little bit of setup there not too bad but now we're ready to start our emulator again and hopefully enjoy the power of cloud fire store so that has been imported I'm gonna click on main I am going to start debugging I am going to pause so you don't have to watch that fire up alright there it goes and you know a lot of you been telling me you've been getting a lot of red print and warnings when you run firebase lately and I'm getting the same thing with the latest version I'm getting less red red print about depreciated api's but it's it's still there it's funny the Google plugin is like Google Maps firebase are some of the worst it's throwing errors like that and it only happens on Android and iOS and tends to run fine so all these Google products are not not working together which is I don't know surprising or not surprising if you ever work for a big company maybe not so surprising but it does seem to work and I did just go to production with an app and I hesitated to to put it in the into the Google Play Store with all this these warnings but it seems to be working out just just fine alright so we want to create a stream here of reports coming in from around the ski area and so let's create a report object and so if we go into the Lib folder and we create a folder called models which looks like I already did but you can right click create a folder and in that models we want to create a new file which will be report Dart and that's where we will model our custom object we will call it class report and so I want four properties here I want a temperature which I'm going to store as an integer in Celsius and if the user has selected Fahrenheit will handle that conversion on the way to the user-interface I want a string for the wax that's being used whether it's red wax Green wax blue wax whatever I want a string for the line of waxes so the company that makes the wax that's being reported and then I want a timestamp so I know when that report came in so I can display that on the screen and also so I can sort them by newest to oldest so we'll have a final integer which will be our temp we'll have a final string which will be wax we'll have a final string which be our line and we'll have a final string which will be our timestamp and I find that easiest to do with firestore is just to have the object be the property be a string in my dart object and store it as a string and firestore and if I use the ISO format it's very easy to convert in and out of date time all right so those are our properties we need to constructor let's do report will do a named constructors so we'll throw we'll do parentheses and then we'll do a couple curly braces and I'm just gonna take them as they are suggested to me this dot temp it's that line doesn't matter the order just taking whatever is thrown down for me and then lastly we're gonna get at a fire store we're gonna get a map and so we want a custom constructor that we can call that will take the map that fire store gives us and convert that into our dart object so we will have report not to JSON we'll call it and we will take that map that fire store gives us it will have a string key and we'll have dynamic values because we're gonna have integers and strings so we've got a mix and we'll call that parsed JSON and so we want to map our temp to our parse JSON temp comma wax is going to equal our parse JSON wax time stamp time stamp will equal our parse JSON time stamp these are all exactly the same because these are the fields in the in the database they don't have to be this is your opportunity to map a field on a database to your property but ours just happened to match as we designed it that way and then we'll do line and then at the end we'll follow it up with a semicolon okay so now that we have a report we want a service to be able to reach out to firestore and get those objects from the database so we can create a services folder on your lib my I already have one so we will add in there we'll add fire store underscore service dot dart and so that's a class that we'll call fire store service makes sense and so we want an instance of fire store so we can do fire store bring that in import it and we'll call it underscore DB and we'll set that equal to fire store dot instance all right so we want a function to get our reports out of the fire store database so that will give us a string up type list of reports make sure we get the double closure there and let's call it get reports I'm gonna need to import our model a report model so we'll let auto import do that there we go all right so it's pretty easy because we're just getting a collection so we can do return underscore DB dot collection and we can tell it that we're gonna look for reports which is where we'll store those reports and so that returns a collection actually it's gonna return a stream of can't get the right thing here okay I'm sorry jumping ahead so that's a collection and then if you did you can either get a stream out of it or a future so if you do get documents you can get a future which will be a query snapshot we don't wanna do that we want to get a stream so let's do snapshots and so that's gonna get us a query snapshot stream and we're not that's not what we want we want a stream of list reports so we're gonna do a little bit more I'm gonna take out snapshot for now I'm gonna go to the next line and let's do more than then we just did there then just grab the whole collection let's start by adding an order by and let's order by timestamp and let's take the we want the the newest report on top so we want to do is descending it's true and now we can grab our snapshots and so this still gets us a query stream and that's not what we want so we can use the map operator to take that snapshot that query snapshot we get we're gonna want to put that in parentheses and right after the closing parenthesis for snapshot we want an arrow function and we're gonna map that to a snapshot item and that snapshot item is gonna have documents in it so we want to get that and then we want to take each one of those documents that comes out and we want to map it to our report objects so let's do another dot map and put the parentheses as well that's our document object and we want to send that to so now we can use our report to JSON actually want to call that from JSON that's what it let me go back to them let's go back to the model go to report Dart I mean it doesn't matter as long as we're calling the right thing but let's let's do from JSON all right and come back to our service here and we'll do from JSON there we go and so we can pass in we've mapped this document snapshot now so we can do document but not just document document dot data property and now we have this is mapped to a iterable of reports so we're closed so we just need to come inside here and cast to list put a semicolon I'm gonna format that I'm gonna slide these out here where I think they should be and there we go so we get our collection we order it by the timestamp dis descending we go ahead and get that snapshot map that snapshot take the documents in the snapshot map those take our report model and our custom constructor which takes a map from firestore and maps it to our report object in dart and then we cast that all back to a list excellent so that gets us our report stream it would also be nice to have a way to add to the report stream the way our app is set up basically we receiving other people's reports and of course there isn't anybody to actually have those reports sent up from so what I'd like to do is I'd like to have a fab button down here and when you click it it'll create a random report which will appear on the screen which will simulate reports coming in from around the ski area okay and so to do that we're gonna create a future that's a thank you you get one key off on a keyboard and it's just total nonsense all right Boyd and we'll call it add report okay so we can add a map to firestore so let's create a variable called data map and we will create a new map with string keys and dynamic values do our parentheses and then we can do return DB collection and the collection we want to add to his reports we can add and we can add our data map all right so that will add that to the collection it's just a blank data map so that's obviously now what we want we want to add some values to it and so to randomize the reports I'm gonna use the random class from Dartmouth so if we come up top here and we do a VAR random and we set that equal random ma equal to a new instance of the random class and we import the random class Dartmouth then we can come down here and create a variable that is a temperature value and we can do a random value for our temperature now the random class has a random number that they will give you and you can pass it a maximum value you can't pass it a minimum value so you can't range with the random package which is unfortunate so let's create our own down here and let's create an integer and we'll create a function called next that will do just that so we'll create an integer which is a minimum and an integer which is a maximum and to get that range effect what we'll do is we'll take the minimum and we'll add a random integer so random not next integers this is a native function from the random packages next integer but it takes the maximum value so we will do max - oops max - min and so by taking the minimum value and taking the difference between the Max and min and taking that as the maximum and adding the two together you create a function that will allow you to range and we've called it next so let's do our call our next function and for our minimum let's do negative 15 and a maximum of five seems like a reasonable range for a ski area in celcius so that'll be our temperature our line which is our company let's say we're gonna have anywhere between negative 15 and 5 so let's split that in half and let's say if temp is less than negative 5 and we use a ternary expression here and let's call that a Swick's and if not we'll call it otoko : there and then for our wax there are more than two kinds of wax but we're just gonna bounce between two just for our purposes here to get a different random going on let's just say if our temp is even we'll call it red and if it's not we'll call it green okay so then down below in our data map once we have our data map we can start adding properties to it so let's say the data map line is equal to our line variable and then our data map wax is equal to our wax variable and the data map temp is equal to our temp variable and then the last property we need is timestamp and that is going to be equal to date/time dot now dot - ISO 8601 string Bing so that is a format that is readily parsed in and out of date time in dart store as well as a string in fire store win-win okay so we got our fire store service we can get our reports we can add a random report this stream is going to be what we want to feed to our main page right here and this is where stream provider finally comes into play so we can come out to our main dart and we can bring that stream into our widget tree right up here by wrapping it with a provider now we could do another wrap on top of change notify our provider with a stream provider or more elegantly we have a solution in provider called multi provider and multi provider allows us to pass an array of providers into the widget tree and that's exactly what we want to do here so we have a property called providers in multi provider we can create a brackets and in those brackets can go any providers with a comma separation that we want to use in our application so we want to we want to keep our change notify our provider and so we can just create I can just cut this this is the remnants of the one I obliterated and we have our change notifier back in our application and then we can do a comma and this is where we can bring in a stream provider and we use a create method just like we did for change notify our provider and in this we can provide the stream that can be accessed anywhere in the application and so the stream that we would like to feed to this is gonna come right out of fire store so let's bring in fire store into our widget here by doing final fire store service underscore DB is what I'll call it and we'll just bring in an instance of that fire store service and the stream that we want to be able to access in the widget tree is gonna be DB dot get reports and in front of that I need to just the same syntax here I need to do a build context context you can actually just put context if you want to just shorthand that okay so that stream is now available in our widget tree for any widget below the main dart file which in our case is just about everything and so if we come up here to home and we want those reports then we can do that by bringing in the provider so in our build if we want to grab that stream we can create a a reports object or a list by doing provider dot of we have the import provider you are semicolon at the end and then come back here to after the of and specify what you are trying to bring in and that is a list of reports and so now this will go up the widget tree and look for a list of reports that it can bring into this widget which is going to be from Maine and it's going to be this DB dot get reports from our fire store service all right we need to import report yeah gonna have to do that manually auto import has been a little sketchy lately so we'll be models with the report dart there we go so if we want to stream those reports we can come down here after our app bar we can create a body in the body we can do a list view dot builder and let's start with item count and that is going to be equal to reports dot length and then item builder it's going to be context index curly braces and so each each item that comes through I want to build a list I'll and I'm going to have a leading so we'll make that a text widget that has actually when I come up here and let's do a report let's just create a report item which will be reports with index and then it'll just save us a little bit of typing here so we can do a report dot temp so that's worked with the temperature and that needs to be cast to a string alright then we want to see a title and so we'll make that a text widget and let's make the title let's make that our wax so we'll do report wax let's do subtitle and we'll do the brand or line underneath that and then for a trailing we can do a timestamp so let's do a text widget let's format that timestamp so if we go to pub dot dev and we go to date format there is a great package there called date underscore format you can go to installing and this one you can install on the fly you do not need to stop and restart the emulator so we can just go to pub spec dot yamo we can paste it below cloud fire store we can save it and as soon as it's done coming down we can access it here and that's done with date format still getting it it's ready do I have that backwards yeah format date sorry about that okay and then so we got report so we have our timestamp is actually a string so we can do time date time dot parse and pass it report dot timestamp then we're in business and then for our formats what you do is you do brackets and you can do hours I'm gonna do lowercase H and u comma separate all the elements of this date format and it smooches them all together so then I want a string that is the colon and then I want and n which is our minutes then I want a space and then I want a.m. p.m. which I can do there so the lowercase H is a single character if you know it doesn't do the leading zero in 12-hour time if I wanted to have the leading zero I could do two H's if I want 24-hour time without a leading zero I could do that and if I want the leading zero I do that so pick your format and we need to return that list I'll okay and so in doing this video I learned something about fire store in that because I have the same package name for my source code and my actual production code it's basically thinks it's the same app and because fire store will try to intelligently store records on your device if it can if it's if it's offline it's basically thinking that the records I added when I did my source code are still valid for this so you do not have records on your screen I do it's okay we'll get around it we'll get through this together so don't worry about that but you can see we have our format we have you know we have a list of records here at least I do because I've got some data you don't so let's give you an ability to add so after our body let's add a fab button and when you click it we're gonna call fire store and we're gonna add a random record so if we come down after ListView and we do a floating action button floating action button I need a child the child to be an icon and we'll do icons dot add and then after that we'll add an unprecedented curly braces hit enter and down here we want to call our fire store add and so let's come up to the top and let's create a fire store we'll call it DB and we'll set that equal to a new instance of fire store service and then we will call underscore DB add report in our floating action button and so when we click that we're gonna call add report it should bounce back to our stream which should be reading that from the newest to the oldest and the new record should be inserted on the top and there we go so we see green at negative 9 degrees Celsius and if we hit plus we get a new record and the green negative 9 has slid down we have done all of this without a stream builder so that is the major advantage of stream provider is that all of the code that goes along with stream provider can go away and you can simply have write like we have here just a list view it is succinct it is elegant it works great now you may have noticed that this is not exactly performing the way we wanted to because we have a settings page and we want to be able to filter this so if I say I don't want to see Swick's or toko I just want to see a blank screen I don't get that and that's because we've just brought in the stream from fire store and we can just go ahead and stand filter right on top of that stream so let's do that so we have values in our change notifier provider that we could use to filter the stream as it's brought out of the provider and so we can do that by just bringing in our cert our settings provider from the settings and so this is what we built in change notifier provider it's sitting over here in the provider folder and we are setting our settings we are getting our settings and we're putting them into the onto the device with shared preferences and now we're tapping into that to filter our stream and so we do provider of and what we want to get is our settings provider and so that's this class here and provider that is storing this data and so coming back to home dot art if we now have these settings what we can do is rather than bring in the full stream here where we have var reports we can come right on top of it and add a where clause and so we're gonna get a report object out of that and what we want is we only want brands that are in the list of strings that we have provided here in our settings widget so in our settings provider we are maintaining through these filter chips a list of wax lines that we want to see and we can now use that to say if settings duh wax lines contains report dot line then we want to see it and lastly we just want to cast that back to a list because that's gonna be an iterable save that I'm gonna auto format which will wrap it a little bit like this and so now the stream that we have is filtered by our settings provider which is a change notify our provider and you can see we have nothing that's because we haven't selected a line and if we say we only want to see Swick's we only get Swick's if we say we only want to see toko that's all we get so that is the magic of a stream provider this is all lazily loaded so you don't have to worry about the fact that in our fire store service we're just getting all the reports we are only seeing on the screen what we need to see and if we scroll down that is being loaded as we call it we had to do virtually nothing in our user interface to bring in that stream we did it just all up here and then our ListView can remain clean let's take care one more thing that we want to do here that we've got a Celsius display over here if we go back into our settings and we display Imperial are we are actually selecting Imperial we don't get it yet so let's come over here to our leading and let's do this if settings dot units equals metric then I'm just gonna put that on another line we'll take that otherwise we want a text with our report dot temp string like that and let's add a conversion here and so we're gonna do some math here eggs alright so let's do for parental L let's do this so we need to take our temp let's get these two string out here let's wrap our report in parentheses and multiply it by parentheses 9 divided by 5 and then we want to wrap that whole thing so wrap here another parenthesis here and so two parenthesis out there right there we want to add 32 and then we want to round that so we need to actually wrap all of that in another parenthesis so another one there around the 32 and another one in front of report so you should have four now in front of report let's see one after temp two after the nine divided by five and two after the 32 so come in between these two will do why are we rounding when it's an integer well after we do this math it will not be and then we can cast that to string and by golly we've got it so one last thing I want to do after the two string let's add the Unicode for the degree sign so backslash u 0 0 B 0 you didn't know this is gonna become a math lesson did you probably wouldn't have clicked on this video if you knew that then let's come up let's copy that we'll do the same thing for metric after the two string will just add the degree symbol okay now I'm happy so that is stream provider really great way to cut down on the amount of code that you have here in your user interface you do not have to use a stream builder which is great we did do a little filtering up here if you were to work in a block you could you could factor that out and not have to deal with that I thought that was a little beyond the scope of this we just wanted to cover stream provider today but it definitely gives me some ideas for future videos so thanks for watching hope you found this helpful my plan next time my rough plan next time is to cover future provider and I think what I'd like to do is implement a Google sign-in directly through Google which will get you a future back with the authentication data and then we'll plug in future provider to receive that as elegantly as we can in our user interface so that's the plan for next time thank you for watching today please like and subscribe found this helpful and we'll see in the next video
Info
Channel: Andy Julow
Views: 15,262
Rating: undefined out of 5
Keywords: Flutter
Id: -gmh5nl9y1s
Channel Id: undefined
Length: 44min 15sec (2655 seconds)
Published: Mon Feb 10 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.