Hive (Flutter Tutorial) – Lightweight & Fast NoSQL Database in Pure Dart

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Nice! Looks like you cannot query the db, are you supposed to load everything and do it in dart then? Client side?

👍︎︎ 5 👤︎︎ u/ArchCatLinux 📅︎︎ Sep 30 2019 🗫︎ replies

Good tutorial, I have started using Hive and it's very good. I would like to find out best practices for doing some things, such as sorting the list in the UI and/or in the database. Is there a best way to track indexes or keys? I will probably have to create a separate data list to do this.

👍︎︎ 3 👤︎︎ u/AlphaState 📅︎︎ Oct 01 2019 🗫︎ replies

Any comparisons to Sembast DB?

👍︎︎ 2 👤︎︎ u/Simderi 📅︎︎ Oct 01 2019 🗫︎ replies

Good tutorial, i have a question, Has support for IOS?

👍︎︎ 1 👤︎︎ u/ladnar_28 📅︎︎ Oct 01 2019 🗫︎ replies

whats the difference between this type of back end and firebase? I understand how it differs in features, kind curious about having an async type of back-end similar to how react.js has socket.io tool for real-time web user updates

👍︎︎ 1 👤︎︎ u/regzy 📅︎︎ Oct 07 2019 🗫︎ replies
Captions
storing data locally is a task which has to be done by almost every app maybe you want to cache responses from a REST API or you are building an outline only app in any case choosing the right local database can make all the difference in how quickly you can develop the app and also in how performant the app will be hive is a lightweight and it powerful database which is easy to develop with and it also runs pretty fast on the device unless you absolutely need to model your data with many relationships in which case you should probably choose something like SQLite or more choosing this pure dart no SQL database with no native dependencies which means that it also runs on flutter web can be the best option hello welcome to resew coder where you are getting prepares for a real app development by building better faster more stable apps so subscribe and hit the bell if you want to grow your coding skills in this tutorial you are going to learn how to work with the hive database by building this simple contacts app which will not really even store contacts you will just store a name and an age of a person so we're gonna have a custom contact class which can then be converted to something which can be stored inside hive using a type adapter we're going to get to that in this tutorial so we can have Jane Doe age will be for example 40 and it's going to be added automatically to the database and it's going to show up immediately inside this ListView and then you're also going to learn how to update a contact or something inside the database and also how to delete of course so we're gonna have a fully functional crud which means create read update delete application by the end of this tutorial all done with hive and be sure to check out the written tutorial from the link in the description where you can also find all of the code written in this video and link to the libraries and also over there you can find the starter project so that you don't have to start completely from scratch so definitely check it out the user interface of this app is not all that difficult to comprehend like there is just ListView and a form which can accept the name and an age of contact and then we have a button and that's basically it just to spare you from writing this from scratch you can also download the starter project and you're going to be left with something like this which is just a clean app it doesn't even have the hive package dependency inside the pops Fujiyama and the starter project when we launch it looks like this we have a blank place view which contains just one item and no matter what we type inside here is now going to be added nowhere because like there's not even the hive dependency it inside the pub spec yamo alright so now let's go to that pops pagamo and add hive and also hive fluttered path provider because we need to provide a path where the hive database file can be stored and on Android it's going to be different on than an iOS so path provider will allow us to specify easily the directory in which to store the database file so all of this goes into the dependencies but then also we're going to be using type adapters so we have a contact class here which contains simply a string and an integer and with the help of a type adapter we're going to be able to very easily store this contact class or its objects thereof inside the hive database and the type adapter generates some code in order to store this contact in the database and in order for the hive library to generate code we need to add a def dependency to hive generator and also obviously to the build runner so that we can kick out the code generation process now once we save pops pagamo we have all of the dependencies in place so we can start working on hive going to start off in Maine de dart because hive needs to be initialized before anything else can be done with it the best place for initialization is inside the main function inside Maine dot dart because this runs before any widget is instantiated so let's just convert this method to block body and inside here we are going to say hi we of course need to import hive the dart package so hive in it and this init method has to accept a string path this path will be the path to the directory inside of which our app has the permission to store data on a particular device and on Android is going to be different than an iOS so that's why we've added the path provider library so that we can get the application documents directory without any hassle so let's also import the path provider and let's import it as that provider now we want to get the app document directory so final app document is equal to path provider that get application documents directory but this is an asynchronous call so we need to await it so therefore we are gonna make the main method also asynchronous and put away the keyword over here and now we can use this app document directory over in the initialization of hive but also this is a directory type so we need to get the path out of it well just call path and now we are good to go hive with boxes before a box can be used it has to be opened and also in addition to plain flavored boxes there are also lazy loading boxes and also boxes support encryption but in this tutorial we are going to focus on the basic boxes that's because they're the most used ones and also you can read up about the more exotic boxes from the links from the written tutorial when you open a regular box its data whatever is stored inside that box inside the persistent storage will be loaded into memory for immediate access so just to demonstrate and of course we're now gonna do it directly from main dart but just for demonstration purposes to open a box you call hive that open box and you specify the name of the box for example contacts and then after you await it you now have the instance of the box so let's just put it inside final contact box and now this box is opened for the whole app so even from a different part of the app even from a different file or from a different widget like for example here the main my app status widget we can now call hive that box we do not need to open it again we can but it is going to return the OL re-open box anyway but we can just call box contacts and now this is no longer a synchronous now we again have the very same instance of the opened contacts box which contains the data stored inside of it and also obviously we can add new data to this open contacts box so we can add we can put and do all kinds of stuff to which we are going to get in just a little while now to keep the code clean you should probably open the box only once and then access it using the hive dot box method and not try to open it like multiple times even though if you do that if we go to the hive dot dot and go to its implementation somewhere in here if we go to open box we can see that if the box is already opened it's just going to return the box which is already open so you can call open box how many times you want but just for the sake of clarity in your code you should not do that if you can avoid it and also before the app closes or when you no longer need the box for example you navigate away from a certain page and you know that this box will not be needed anymore unless you go back to that particular page you should also close the box so let's do these things opening the box only in one place and then closing the box before the app closes itself let's do them right now let's just delete this line where it's now going to need it and a box should be opened before anything else which needs that box to be opened runs so we're going to use the box from within the contact page so before this contact page is built the box should be already opened and you could technically open the box from the main method and open all of your boxes in here but that's just not a good practice because regular boxes if they are not lazy boxes and you can again read up more on them from the link in the video description from the written tutorial unless they are lazy all of the contents of the box so all of the data stored inside persistent storage will be loaded into memory so that it can be accessed very fast so therefore opening all of your boxes from the main method is probably not the best wisest option instead you want to open boxes per page for example inside contact page you would open the contacts box right or in this case because we have just one page we can also open this box from within the my app class it doesn't really matter in our case and to open a box like that which is returning a future this method we need to use a future builder widget so let's wrap the contact page inside a future builder widget so I'm going to use awesome water snippets for future builder we're going to say that the future is the hive dot open box call so let's put it over here initial data it's not gonna have any initial data future builder and then the builder will of course return the contact page which contains the ListView and all of that but we obviously cannot just return a contact page like this we first have to find out about the connection state of the future so as usual with future builder we're going to first check if the snapshot which contains the information about the future so this snapshot that connection state is equal to connection state dun dun so if the future is completed which means that the box is opened in that case when the box is opened we want to return contact page however there can be some errors possibly with opening the box so we also have to handle the error case so if snapshot that has error we're just going to simply return text which will contain the snapshot that error message so we are just going to convert the Arab to string and otherwise we're going to return contact page and all right flower thank you for notify me about high being not initialized that's because we have not ha to restarted the app so once we hit this hard restart or ctrl shift and f5 button this error will be gone or actually we have to stop the app and restart it again so let's do just that alright so here we go but did you see that error for that brief moment the red screen appeared because this builder until the connection state of the future is done which means that the box is opened until that happens this builder returns nothing which in darts terms sadly means that it returns null and even though open in the Box really takes just a short time we need to handle the case when the future is not yet completed so the box is not opened and in that case we still need to return some UI widget so we're just going to return an empty scaffold and now when we had restart we should not see any errors and surely we did not see them so that's awesome all right so we have the box already opened whenever the app is loaded and in some more elaborate app you would do this on a per-page basis so if you were to navigate to contacts page with a navigator you would only then open the contacts box and then whenever you would leave the contacts page to go for example to the home page in your app you would probably want to close the contacts box it's not a disaster if you do not do that if you do not close the box but still why should you hold unnecessary data in the memory when you can release it so that's why we're going to close the box whenever the my app widget is disposed and for that we obviously need to convert this my average it to be stateful and now inside this pose we can either close only the contacts box so we would say hi dad box and specify the name contacts and now we can use the close method or also you can do something like hive dot close which will close all of the boxes which are currently opened so because we have just one box it doesn't really matter what we do here but let's just leave it at hive dot close which potentially can close all of the boxes if you have opened multiple ones so now this - is realization and opening and closing of boxes is fully done we have initialized hive inside the main method and then we are opening the box before a page where it needs to be used has the possibility to be even loaded so that's cool and also we dispose of all of the boxes where we release the resources from let's now move over to the new contact form because inside contact page we really have just an app bar and the list view here which simply currently holds only a single placeholder list style which says name and age as you can see it's basically a non functional is view and then we have this new contact form which is a simple form which gets name and age input from the user and whenever the button is clicked this race button when that's clicked we construct a contact containing a name and an integer age and we call add contact which is a simple method which currently only prints out the inputted contact data to the console so if we input name something like John Doe and age will be 20 and then add new contact and open up the console so the output or debug console actually there will be written name John Doe and ages 20 so that's working as expected but obviously inside this add contact we do not just want to print out the contact information to the console we actually want to add the contact to the hive database so let's leave this line and now there are two basic options of adding data once we have the box and remember we can get the box instance by calling hive dot box and specify its name so contacts we're gonna need to import hi package and now once we have the box we can either call put this is the first basic option of adding data to the database and we can specify the key ourselves so for example contact one and keys can be either strings for also integers so for example one can also be the key and then input the value which would be contact then the another option is that we can use the add method and this will make hive use auto incrementing keys so the key will be now zero then when we add another contact it will be one and two and so on so we don't have to take care of the keys ourselves when we are adding contacts and unless you need to absolutely specify the key yourself you should probably just always use the add method but here's the problem when we now save and run this code and open up the console when we try to add the contact so John edge will be five at contact we get hive error however cannot write unknown type contact did you forget to register an adapter and did we register an adapter well we didn't that's because hive out-of-the-box supports only regular dart types for example integers strings boolean and even lists and maps it even supports date times out of the box but our own model class contact hive obviously doesn't have any clue how to store it inside the database and obviously you could solve it by doing something by converting the contact to JSON in which case it would be a string and strings obviously can be stored inside the database but hive offers another option than just storing JSON strings because you can use custom type adapters with hive and it will convert the data present inside the object to a binary format so let's utilize this option which hive offers and let's create a custom tired actor for our contact class over in the contact on dart file we have this simple class which contains only string name and int age and to create a type adapter you can either do it yourself manually or you can utilize the hive generator package which we've added over here and let this generator generate a type of actor for you I this generation is the better option because you can make some mistakes and it's really clunky if you write it yourself I would say that you should always leave it to the generator unless you have some absolute reason to write it yourself manually so let's import hive and over here we're going to annotate the class with hive type so the class is hive type and then it's fields are going to be hive fields and you also need to specify an index for each field so the first one will be 0 and then the second one 4-h will be 1 there are some precautions which you should take whenever you annotate with these high fields and specify their numbers for example if you decide to update the field or add new fields the numbers of the old fields should not change you can read more about this from the written tutorial which has all the links to the official documentation in our case we are not gonna need to update this contact class but in order for this hive generator to kick in we of course need to specify the part of the file which will be generated so it's gonna be called contact dodgy dart and now we can run the flower developers most favorite command which is of course flutter packages Bob run Bill Runner and now we can just say build because we are cool which is one out build we do not need to watch this and there are some problems here so after reading through Stack Overflow I found out that the newest version of Bill Runner which we are using just does not work oh my so it's probably not even the pups pajama version but it's this analyzer and pop spec lock so whatever just let's save that and hopefully even after I changed the bill ground to be the latest version hopefully it will run now so let's hope for the best what early bugging is really amazing awesome I finally managed to build this so if you have these kinds of issues hopefully do not have them just change the version of the analyzer inside the top spec deadlock file so I hope you will not have these issues but if you do just do that and you will be good to go all right so now that we have this contact that G dot dot which contains the generated type adapter we can now use this contact from within the new contact form to actually add it to the hive database but just generating the adapter is not enough we also have to register it and we can register it either for just a single box for example for this contacts box or we can register it for all of the boxes inside the hive database and in our case it doesn't really matter because we have just one box so we're just going to register it globally so after it's initialized we are also going to call hive dot register adapter and pass in the contact adapter which is the class which was just generated and let's also specify the type ID so starting from 0 will be the type ID and then an R type ID would be 1 2 and so on now that we've done that we can go to the new contact form and add a new contact to the database just like this and actually just to make this a bit more clean let's extract this to a new final variable which will be called contacts box and we're going to call contacts box that add here so whenever the button will be clicked inside the form we're going to construct a new contact object and pass it over to the add contact method which will in turn add the contact to the hive box but of course doing just this would be of no use to us because we are currently not reading the contacts so even though after I shall restart the app so even though we can add a contact John and age will be 20 and we are no longer going to get that nasty exception nothing really happens in the UI so let's now go over to the contact page where there is the ListView and let's read the contacts from the hive database so inside this method build ListView we're going to get hold of the contact box final contact box is equal to what else then hive that box so let's import hive and we want to access the contacts box and now inside this ListView it will no longer hold just children but it will be instead of this view builders so let's cut out the list style and we're going to call this view dot builder and a builder needs to get its item count specified and we can find out the number of stored contacts or some other entries from a box by calling the box dot length and now for the ListView builder so item builder actually which will grant as a context and index inside of here we are going to return the list style and now we want to somehow populate the title in subtitle with the data from the contact box for the contact on the particular index the simplest way to retrieve the is by calling contacts box that get which takes in a key and because we are using auto incrementing keys if you remember inside the new contact form we call add and writes here that this saves the value with an auto increment key so because of that we should be just able to specify the index as the key right but of course we are now going to specify directly inside the text instead we want to get the contact out of the database so we're going to create final contact and that will be equal to contacts box dot get and then we want to cast it as a contact which we need to import of course and then we will just pass contact that name to the first title text view or text as it's calling flower and then the subtitle would be contact dot H right of course convert it to string so we could do that of course if we now take a look at the app it shows John 20 which is the contact which we have added previously to the database so it works but it's not the safest option although we're currently only adding a contact to the database by calling add what if we added a contact calling put and we would put a new contact in there specifying a custom key for example hundred and twenty three or what if we delete the contact what will happen then well in these cases as soon as you do not just use auto increment keys all the time but you also put some data in there and delete our data from the box you will no longer be able to rely on the fact that the keys are just incrementally increasing for each contact inside the box because after all we could have just two contacts in the database but the first ones key could be zero and the second contact could have the key of 1,000 there is another way to access data from within the box and that is the get at get a doesn't have a key argument instead it accepts and index so let's talk about the difference between key and an index in a way hive works sort of like a map which can be accessed with keys which you can specify and customize to your liking but it also works in a way as a list where every new item added to the hive box has an index which is incremented just like when you have two entries inside a list one cannot have the index of zero and the second one next to it cannot have the index being 1000 indexes or indices in a list are always incremented gradually and this is the same for hive boxes so the bottom line is you should not rely on keys and indexes being the same and unless you absolutely need to get the value by its key you should get it by its index especially from somewhere like item builder of a ListView alright so let's just have restart the app to be safe and when we now add another contact so Jane it will be also 20 maybe and add new contact nothing really happens until we have restored the app again and now we have both John and Jane so what's going on well of course we are adding new contacts to the database but those contacts are not automatically being read from the database because reading from the database currently happens only when the ListView is built and this happens only when this contact page is built which happens only once that's why I provides a watch method which you can call on a box so for example contacts bars that watch you can optionally specify a key if you want to just watch specific keys inside that box but if you wanna watch the whole box you can just specify watch and do not add any keys there and now we can listen to it and do something else with it because watch returns a stream and of course in flutter you can use a stream builder to work with streams and this is actually plenty enough if you work with some proper state management for example with block where you do not expose boxes directly to the UI however if you are doing some just simple state management like here where you are basically accessing the boxes directly from the UI and you should not do that in your Production apps if you want to learn more about that you can check out the full free course from the cart in the corner where you are going to learn about clean architecture but if you are really just hacking some app together and you want to expose boxes directly to the UI you can use a watch box builder and not bother with creating stream builders and working with raw streams we're going to use the watch box builder to wrap this lace view so let's do just that we're going to cut out this ListView and instead return watch box builder this comes from the hive flutter package and we need to specify the box the Builder which grants has a context and the box so contacts box let's just base quickly this ListView builder into the Builder of the watch box builder - many builders at once so the box should of course be contacts so let's put it in there we can now delete this contacts box final variable and of course let's change the return type of the build this view method to be just widget and now after we remove some unneeded commas and semicolons we have it working now whenever any kind of a value changes inside the contacts box this watch box builder builder method will triggered which in turn will rebuild the whole ListView so now if we go to the app and add a new contact contact it will be one edit we can immediately see it displayed inside the ListView now the last part of a crud application is updating and deleting we're going to perform these updates and deletes using just simple buttons inside this list style for a contact because we want to keep this simple so let me just add trailing to this list style which will be a row which will have main exercise to be minimum so that it just wraps the two icon buttons which will be present inside the row as children because whenever we press an icon button for updating we're just going to update the contact with some asterisk added after its name so it will be contact asterisk after its being updated so let me just quickly add icon button which will have an icon of icons the Refresh and inside unpressed we want to update the contact inside the database now how are we going to do that by taking a look and the contact box we can see that there is no real update method instead what we can do is basically overwrite a contact on a particular index or a key and since we are working with indexes here we are going to say put hat because put ad overrides a contact or adds a new contact on an index but put add a new contact or overrides contact on a key so we want to use put add the index will be index which we get from and placed views builder and the value will be simply the same contact which is already present in the a base but we're going to create a new instance of it and just change the contacts name so let's interpolate that and the name will have an asterisk added to it and the edge will remain the same so contact that age nothing changes there or let's actually just add one year to it just for fun so now we can see that we have the refresh button and when we press it John will be 23 years over 24 years old and he also has four asterisks added after the name and similarly we want to have a button or an icon button for deleting the contact so let's just paste it over here it's going to have icon the elite and the Lee thing a contact is very simple we again can use either delete to delete the contact on a particular key or we can also use the lead at you can also delete all or delete everything that the hive is storing from disk but that is not cool so you should avoid using that method or use it with caution rather but in our case we want to delete at a particular index and once we do that and go to the app we can delete for example Jane alright although we have all of the crud functionality implemented in this simple contacts app there is one more thing worth talking about when it comes to hive that's compaction of boxes I will quickly read you what is written inside the official documentation hive is an append-only data store when you change or delete the value the change is written to the end of the box file this leads sooner or later to a growing box file and hive may automatically come back to your box at any time so basically our box when we delete a value or overwrite the value has some holes for the lack of a better word inside of and these holes take up space and they need to be compacted so that there will be no more holes inside that list which is present on the resistant storage and it's completely fine to leave it up to hive itself you do not need to override the compaction circumstances but also just so you know you can in fact change when the hive database is being compacted this could be useful for example if you have a lot of data store inside database and you do not want hive to compact on app launch for example because you could freeze the app and you definitely do not want to freeze the app when it launches because that's just poor user experience but if you absolutely need to override the compaction logic you could do it for example before the hive database is closed or before the box itself is closed but because we are closing the whole database anyways let's just do it inside the dispose method of our my app widget so inside of here let's just call hive and we need to compact a particular box so contacts in this case and let's just call compact and that's it so now we have added our own custom point at which the box should be compacted but in addition to this we can also change the conditions under which the compaction will happen these options which we are about to write obviously do not affect your own custom compaction points but if you leave it up to hive to compact you can modify when it compacts we can modify that while we are opening the box so here inside the future builder when we open the box for contacts we can also specify compaction strategy which is a boolean returning method or higher order function to be more precise it accepts an integer total and also integer deleted so of course those are the numbers of entries one is for total number of entries and one is for deleted number of entries present inside the database so that's basically the amount of holes inside the list and for example we can say that it should only compact when the amount of holes of the deleted entries is greater than 20 so delete it is greater than 20 by default the compaction strategy for hive is 60 and it also has some other logic in there which looks at the ratio of total entries and deleted nth reason decides whether or not to come back based on that ratio but you can of course go to the source code of high because it's completely open source on github and links are in the written tutorial to which you can get from the link in the video description you should just know that you can absolutely override everything that hive does so it's really awesome that it's so customizable to go through this tutorial at your own pace once again and to get all of the code and all of the links check out the written tutorial available from the link in the video description in this tutorial you learned about hive which is a performant and easy to use database for flutter there are constantly new things added to it for example the author Simon lyre is working on adding queries to this database because currently it doesn't support queries but they are on the horizon they are gonna arrive pretty soon or they actually may be already in there if you are watching this a bit later and so if you do not want to miss more tutorials like this including the one on queries in hive once they come out definitely subscribe to this channel and also join the notifications quad by hitting the Bell button to make sure you grow your flutter skills because here on reso coder I am determined to provide you with the best app development tutorials and resources out there if this video helped you with understanding hive how to use it and also if it helps you with debugging Beast stupid built runner errors in flutter by changing the pups peg lock analyzer version and give this video a like and also share it with our developers who will surely benefit from this student we become and if you have anything to say and see you in the net [Music]
Info
Channel: Reso Coder
Views: 67,359
Rating: 4.9674354 out of 5
Keywords: resocoder, tutorial, programming, code, programming tutorial, flutter, flutter tutorial, hive, flutter hive, hive database, flutter database, flutter persistent storage, flutter nosql
Id: R1GSrrItqUs
Channel Id: undefined
Length: 42min 13sec (2533 seconds)
Published: Mon Sep 30 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.