When learning a new tool or technology, everyone usually tries to build massive projects like e-commerce apps or social media clones. Instead, I turned to a much more focused and simple project to wrap my head around a new local database solution: a Minimalist Habit Tracker.
My goal was to focus directly on database operations and state management integration without getting lost in complex UI designs or API integrations.
So, why Isar?
For Those Who Don't Know: What is Isar?
When Flutter developers think of local storage, SQLite, Shared Preferences, or Hive usually come to mind. Isar is a next-generation, blazing-fast NoSQL database developed by Simon Leier, the creator of the legendary Hive package.
What makes Isar so special:
- Blazing Fast: Thanks to its C-based engine under the hood, read/write speeds are massive.
- Fully Type-Safe: It prevents string-based errors when querying. You can write your queries safely with auto-completion.
- Advanced Queries: It offers out-of-the-box capabilities like full-text search, filtering, and multi-indexing.
- Visual Inspector: While your app is running, you can view the inside of your database live on your browser, just like an Excel spreadsheet.
How I Structured the Architecture
To prevent the code from turning into "spaghetti," I applied the classic "divide and conquer" approach:
-
Models: Collection schemas leveraging Isar's power (
Habitclass). -
Services: An isolated layer handling database CRUD operations and date updates (
IsarService). -
Providers: The
HabitProviderthat acts as a bridge between the UI and the Isar service. - Screens: A clean, minimalist interface for user interaction.
The Real Deal: Where Did I Struggle and How Did I Solve It?
Everything looked great on paper, but I hit some walls in practice. Here are those issues and my practical solutions:
Wall 1: The Gradle and "Namespace" Rebellion
When I installed the Isar package and tried to build the project for the first time, the Android Gradle engine threw an error. I realized that the isar_flutter_libs package didn't comply with the "namespace" rule and the minimum SDK 34 requirement demanded by modern Flutter projects.
- ** Solution:** Instead of spending hours searching for a fix online, I went straight to the heart of the package inside the pub cache. I manually added the
namespace 'dev.isar.isar_flutter_libs'line to the package'sandroid/build.gradlefile and updated thecompileSdkVersionto34, solving the problem at its root.
Wall 2: Provider's Silent Scream: `T != dynamicTried to call Provider.of` error.
When I tried to save a new habit from the UI, the app suddenly crashed with a
-
Solution: I realized the issue stemmed from a very simple typing omission. Dart was essentially telling me, "I don't know who you are talking to." By writing
context.read<HabitProvider>().addNewHabit()instead ofcontext.read().addNewHabit(), I experienced firsthand how critical it is to strictly specify the<HabitProvider>type.
Wall 3: GitHub Thinking My Project was an "HTML Project"
I proudly pushed the project to GitHub, only to check my repository's language stats and see 7% Dart and 90% HTML!
-
Solution: I immediately created a
.gitattributesfile in the root directory of the project. I told GitHub's language parser to ignore certain autogenerated folders by adding this code:
*.html linguist-generated=true
web/** linguist-generated=true
build/** linguist-generated=true
The result? My Dart percentage went right back up to its well-deserved 100% level!
Conclusion and Takeaways
This small project showed me this: The best way to learn a technology (especially a powerful database like Isar) is to abstract it from complex app structures and use it in its most fundamental form.
If you'd like to check out my project or take a look at the code, I'm leaving my repo link below. I'm looking forward to your comments and code critiques!
Top comments (0)