Pulling Data from Firebase Cloud Firestore in Flutter - Roman Just Codes (S1E13)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everyone welcome to the flutter development series from roman just codes where i'll be developing beautiful user interfaces with flutter and in this video i'll be pulling data from the cloud stored in firebase cloud firestore while replacing the hard-coded data that's powering this application in this series i've been building the ui for a fictional grocery and produce app and for this episode i'll be covering the usage of the flutter package for cloud firestore to pull data from the cloud and the ability to consume and parse this data within my flutter app this is what we'll be tackling in this video i'll be using cloud firestore as the backend service for this app and i'll connect to the firebase instance in the cloud in order to pull all required data to feed the category widgets that show on the app instead of being hard-coded in the app as before the data will be stored in documents and collections within firebase cloud firestore i'll optimize this app so it retrieves this data prior to starting up during the splash screen loading sequence that way i can use my app with data that's already fetched we'll talk a bit about cloud firestore and the data structure in a minute let's proceed in the previous episode you recall me adding this hard-coded data structure full of category objects that contained subcategories and category parts all hard-coded on the app for the sake of creating the widgets and powering through the development of this app now it's time to get rid of it and replace it by data coming from a backend service and our top choice to store and retrieve it is firebase since we've already leveraged its authentication capabilities in the existing firebase project for this app navigate to the firebase console and on the left navigation select firestore database for the sake of this tutorial i've already created the data required for this app but i'll go over it anyway exactly the same data that was hard coded has been stored here in firestore cloud firestore is a nosql document database that lets you easily store sync and query data for your mobile and web apps at global scale structure your data easily with collections and documents collections store documents and documents can store other pieces of information in our case our document contains a map with a key called categories which contains an array of map objects as its value each map contains additional key value pairs like any other json object would that correspond to the models that we are consuming in our flutter app you can build complex hierarchies with ease like mine since each category contains a collection of subcategories each of which is a map of its own and each subcategory in turn contains a collection called parts which corresponds to a category part in rui in this collection i have six map objects that i would like to consume if i want to add one more for example it would be as easy as adding another map to this collection with keys and values i can set the type of my values from a predefined set which makes my structures very flexible you can easily delete any entry from this property so this is the data we'll be working with and with that let's proceed to the code and how to pull this data from flutter back in our code let's start by modifying the pop spec diamo so we can import the cloud firestore package make sure you're adding the appropriate version then save with that out of the way let me show you where in the episode where we implemented firebase authentication we are initializing the connection to firebase here in the login service is where we are currently initializing the firebase application this initialization must be done outside of the service now since we don't want to depend on this service to be the one bootstrapping the app now we want this initialization to happen much earlier at the beginning of our application during the splash screen sequence way before we display anything so remove it from here completely let's go to the splash page widget since it's the first page that displays and here's where we'll initialize the connection to firebase right after the splash screen delay but before proceeding any further this will guarantee that our firebase app instance is initialized before we start pulling any data from firebase or even performing authentication since this returns a future meaning it's an asynchronous call we will wait on it before proceeding by implementing a sync and a wait on it once i've ensured that the firebase connection has been initialized it is then when i can start fetching data from it not before now at this point it would be safe to pull the category information stored in cloud firestore let's start doing the refactoring of the splash screen so now it shows a circular progress indicator while both the initialization of firebase and upfront data fetching are occurring i'll comment this line out so it spins forever while i refactor it okay so i'll refactor this piece and instead of the icon widget being the container's child it will be a stack widget since i'll overlap both icon and circular progress indicator i'll wrap the icon widget inside and aligned widget and align it to the center i'll add a circular progress indicator widget with a value color of white with a 50 opacity make it a bit larger by wrapping it inside a fixed sized box widget 150 by 150 pixels thicken the indicator stroke by adding a stroke width of 10. wrap it inside an align widget and align it to the center of the stack as well so it shows right on top of the icon widget i'll adjust the size of the icon and set its size to 80 pixels much better let me uncomment the navigation to make sure things are still in order now it's time to fetch the data from firebase i'll encapsulate all the firebase data retrieval functionality in a convenient class called category service inside the services folder don't confuse it with the category selection service one is for selection related activities the other one is for data fetching inside this class create an instance of firebase firestore let's call it instance and make it private to this class we'll only use it inside here this class will serve a list of category models called categories also private i'll create a convenient getter for this property to keep it really encapsulated called get categories and i'll create a method called get categories from firestore this is the method that will do the initial retrieval of the data from firebase and since this is an asynchronous call i'll return a future out of it and decorate it with the async keyword i'll show you why in a minute so assuming that our firebase app has been initialized i can proceed and make calls against it first retrieve an instance of firebase firestore from well firebase firestore this will give you a direct connection to your firebase instance in the cloud create a collection reference called categories and pull it out of the instance dot collection call remember that's how firestore structures the data in collections and documents first thing you query for is the collection which is the topmost entity grab the name of your collection and plug it in the instance dot collection call you should have a reference to this collection now out of this collection fetch a document snapshot and store it in a property called snapshot use the categories.doc call which is a synchronous and a weight on it the only document this collection has is here so grab the name of that document and plug it in the categories.call then do a get on it once it's retrieved unwrap the data it contains by calling the method data on the snapshot and casting into a map your data is all of this which is a map with a single property also called categories which is in turn an array of other maps now i can grab the data stored in the categories property by just referencing the key named categories simple as that this will return me this whole array containing six map objects i'm storing it in this property called categories data i'm casting it as a list of dynamic objects i could have also done it as a list of map each one of these objects will correspond to these maps which contain the data i'm interested in consuming since this is a list i can easily loop through this collection and map each object into the desired model to be consumed this model has a color icon image name name matching on the properties available in my category dart model subcategories also have similar properties and a bit more and parts inside subcategories also has its own structure i think i'm ready to proceed and map this data to dart models and just feed it to my widgets i'll start by modifying the topmost object in the structure the category model as customary dart provides a factory constructor method that as best practice it is used to create instances of the same class in question people usually create one factory method called from json for mapping adjacent structure to the class it applies and they do it as follows return an instance of the same kind and just hydrate the properties in this new instance with the values coming from the json map they call this a podo a plain old dart object i'm populating all the properties for example this is the color which is a hex string in firebase which i'm converting to a dart color instance pass the icon name image name and for subcategories since this is a collection of another type of photo we'll have to do a similar approach and create a static method that churns out collections of the objects the json list contains in the subcategory model class i'll create a static method that creates a list of subcategory models from a json list of map objects i'll call it from json array when i get the value out of the subcategories key i'll get an array of these maps which i'll have to further parse all of these will correspond to a subcategory photo object and then append it to the category let's go to the subcategory class and add this new method called from json array which returns a list of subcategory objects and takes in a list of dynamic maps [Music] just like in the category model i'll be able to loop through this list of maps and for each map i'll create a corresponding subcategory model as i'm looping i'll be adding the created models wait i need to add also a factory constructor to this class that creates the individual subcategory models i'll do it the same way as in the category model i'll call it from json as usual which will take a map object return a subcategory photo add some of the default values and populate the ones coming from the service name image name color icon some values you can just pass them straight up but some you may have to further process like this one which i convert to a double upon reading it for the parts collection i'll do the same treatment as the subcategory we need a factory method that generates a list of category parts when i fetch the value of the parts key i'll get an array of these maps each of which needs to be parsed appropriately when you show the details of a subcategory these are the category parts i'm referring to so in the category part model i'll add a non-existent from json array method which takes the value of the parts key in this map in the category part class create this method and do pretty much the same thing i wish there was a more automated way of mapping these values but at least i like the fact that you get a lot of fine grain control by doing it this way since you know which properties you want to populate massage the data before assigning it etc as you look through the list of maps create a category part photo object and add it to the parts collection to later be returned and assigned to the parent subcategory this model has two properties that i want to consume image name and name so i'll do just that i'll generate a photo object by creating a corresponding factory method from json passing the map in the iteration [Music] populate the name image name and i'll set that is selected to false as default i'm all set with a subcategory list generator method as well as a factory method that cranks out subcategory instances all of that triggered by the category instance as we read all the values in the hierarchy again to recap we have a collection with a single document which contains a map with a nested structure of categories subcategories and parts to be parsed out and mapped to photo objects to later be consumed by our ui now back to the category service where it all started i'll read the values from the categories key a list of maps and map each one to a category model and well you know the rest each generated category then is added to the internal collection of categories let me simplify this by condensing it to a single line nice so we pull the firebase firestore instance fetch the collection pull its document asynchronously grab a snapshot of the document data and get the value it contains from the corresponding key loop through it and map it but not before initializing the firebase app instance of course which occurs during the splash screen sequence now let's consume this newly created service so we can fetch the category data upfront at the top of the build method retrieve an instance of the newly created category service from the provider we'll be injecting this service as a provider in a minute so other widgets can pull its data right after the instantiation of the firebase app not before call the category services get categories collection from firebase since this is an asynchronous call you can either wait on it or hook on a callback to the future it returns using the provided.then method i'm using this approach so you can see that this will wait until the firestore data retrieval is done before proceeding with whatever we add to this callback then and only then is that we can proceed further into the application by navigating to the welcome page i'm consuming this service here and now i'll add it at the root of the app so it's discoverable by this widget add it to the multi-provider widget list of providers and import it this should do it with this in place i'm happy to say that i'm satisfied with how simple flutter allows developers to integrate firebase into our apps so i'll fetch the service and after firebase initializes i'm free to start fetching data from it asynchronously then proceed further into my app let's take this for a spin pun intended the splash screen spins initializing firebase and fetching the data if you get to this point that means something must have worked but if you go in further recall that we are still showing the mock data from our utils right here in the category list page widget i'm ready to delete this so i can start consuming cloud data from firestore i'll even go as far as removing the whole method that generated this data i mean i can use it for testing but i want to show you proof that nowhere in this app i'm pulling hard-coded data so goodbye mock data now let me prove first that no data displays at all now let's plug in the data we fetch from firebase cloud firestore fetch the category service from the provider and now call the get categories method from this service assuming the data is in memory after being fetched initially and stored internally in this collection running the application once again and there you go the app is fully functioning without hard-coded data and pulling content from the cloud via firebase cloud firestore still not convinced i'll prove its data from firestore check this out i'll change the value of one of its subcategories and rerun the application just to prove that this is data from firestore okay reload the app see i can now claim that this app is powered by firebase since i've integrated both firebase authentication and firebase cloud firestore in it i love the fact that i'm using firebase as a backend service and data repository but its true power lies in its real-time update capabilities and security rules which we'll see in upcoming videos where we'll combine the power of firebase authentication to associate data to a logged in user store and retrieve data in real time and more on firebase and flutter in the next video i'll be leveraging firebase cloud firestore to store shopping cart data from a logged in user add and remove items to the shopping cart and store them in firestore for later retrieval so stay tuned for these cloud firestore upcoming videos thank you everyone see you on the next one that's it for this video so please stay tuned for more upcoming videos hit the subscribe button to stay updated and please like this video if you found it useful thank you so much for watching
Info
Channel: Roman Just Codes
Views: 19,308
Rating: undefined out of 5
Keywords: flutter, stateful, widget, setState, cross-platform, ios, android, desktop, web, declarative ui, user interface, beautiful user interfaces, prototyping, dart, widgets, custom markers, flutter engage, Flutter 2, #FlutterEngage, Flutter community, Flutter developers news, mobile app developers, web development, Google Flutter, authentication, google sign in, google cloud, firestore, firebase console, provider, multiprovider, services, flutter services, changenotifier, firebase, cloud firestore
Id: R015EukCnYI
Channel Id: undefined
Length: 19min 58sec (1198 seconds)
Published: Tue Jun 08 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.