I’m working on a meal planning app, and one of the features I want is for it to be usable offline and to have user account creation be optional. So my thought is to ship the app with ~200 recipes stored locally as a JSON. The user would need to be able to write to it as well.
I’m new to both Flutter and app dev, so I’m wondering how the idea strikes you? Any pitfalls and/or better options?
The point is that assets get bundled with the app so it’s easy to distribute and then to initialize your local database on the Filesystem from the asset because you can’t write back to assets.
path_provider just gives you the locations of the platform Filesystem where you normally store your data.
We currently store everything in folders leveraging the Filesystem as hierarchical database you could say with json files because we don’t need any queries so I didn’t want to add any database packages.
If you need more complex queries sqlite or ObjectBox would be my favorites
My take after few years of trial and error is following. In most of the use-cases the SQLite database (or several if you want to separate it) checks all the boxes:
it’s super common in programming so it’s easy to find references how to use it and build stuff
you can export it as a file to your computer and debug easily with a myriad of free tools (e.g. https://sqlitebrowser.org/)
there are amazing Dart/Flutter packages, my favorite is drift, but there are also other great choices like floor
it’s easy to make it encrypted with SQLCipher
you can access it from native code if ever needed (e.g. home screen widget, foreground service)
you can sync it with the backend - either manually or using some 3rd party tools (powersync etc.), I do it manually and have some models mirrored between backend and local database
you can listen to queries via Stream subscriptions, meaning your UI can just update anytime the underlying data changes
you can store binary data if needed
objects can maintain relations so changes are reflected between them
you can access the same database from multiple isolates to have non-blocking access to data
the maintainers are nice folks and tend to help and answer issues quite quickly
There are some challenges too:
you have to implement and maintain migrations, we use some step-by-step migration helpers, and after almost 2 years we’re at schema version 30+; we will probably get rid of some migrations and just create a new database at some point
you have to create mappers for custom data types (e.g. uuid, json, lists)
you cannot write to the same database from multiple places at the same time, you either have to think about locking mechanism, queuing or falling back to database WAL mode/busy_timeout etc.
sometimes errors are quite cryptic if they come from the native low-level realm
So if you intend to use database, imho spend some time learning about SQLite. After that most of the solutions like objectbox, realm, or sembast will be easier to grasp, and you will get a good comparison reference. They all have shiny features, but imho most of them is not that needed in day-to-day work.
I would suggest SQLite with drift. It will load files faster than the filesystem, can flexible query needs, has beeb around longer than flutter has existed, and also super fast and scales with your application.
I have bad memories working with JSONB and would not recommend it if you plan on doing queries with the data contained in the JSON especially if there’s multiple layers of nesting
Flutter and the related logo are trademarks of Google LLC. We are not endorsed by or affiliated with Google LLC.
Using contents of this forum for the purposes of training proprietary AI models is forbidden. Only if your AI model is free & open source, go ahead and scrape.