[App Development Journal] Day 25: Managing Flutter local data

Managing Flutter local data

Day 25 of non-major app development. Currently, the desired feature in the project is working (searching and saving the results). However, the data disappears when the app is restarted or when switching from one tab to another and back to the list. Today, I learned how to save data in the app and applied it to the project.

[App development Journal] Day 24: Absolute positioning of the Flutter UI

Exploring Local Data Management in Flutter and Applying it to Your Project

Four Options for Managing Flutter local data

There are quite a few ways to manage local data in Flutter.

Hive, SQLite, ObjectBox, SharedPreferences

I will briefly write about these four methods, and then record why I chose a specific method.

1. Hive

Hive is a lightweight and fast key-value database written in pure Dart. It is suitable for applications that need a *NoSQL database and require good performance. Hive can handle more complex data structures than shared_preferences and supports **asynchronous operations.

*What is a NoSQL database?
NoSQL databases, also known as “non-relational databases,” are not traditional tabular databases, meaning that data can be stored freely without a strict structure. This structure allows for flexibility in handling different types of data, which is advantageous when processing large amounts of data very quickly.

**What is an asynchronous task?
Asynchronous work is a way of allowing multiple things to happen at the same time. For example, just as a computer can run a programme and listen to music or write a document at the same time, a programme can save or retrieve data at the same time without stopping other tasks. This makes things much faster and helps programs work more efficiently.

Installing Hive

You can use it by adding Hive and a path provider to your pubspec.yaml file.
    sdk: flutter
  hive: ^2.0.4  
  hive_flutter: ^1.1.0
  path_provider: ^2.0.2  
Since Hive boxes open asynchronously, you can use widgets like Flutter’s FutureBuilder or StreamBuilder to manage asynchronous data. This allows you to dynamically display the data in your UI.

2. SQLite

SQLite provides a relational database management system (RDBMS) and is available in Flutter via the sqflite package. It is especially useful when you need to manage data with a complex structure or relational data.

Installing SQLite

Open the pubspec.yaml file and add it to the dependencies section.

    sdk: flutter
  sqflite: ^2.0.0+3  
  path_provider: ^2.0.2  

Allows for multiple tables, complex queries, and establishing relationships between data. Suitable for large datasets, allowing you to flexibly store and manage data according to your database schema (database structure).

3. ObjectBox

ObjectBox is a fast NoSQL database for mobile apps. It is advantageous when large data volumes and high input/output speeds are required.

Installing ObjectBox

    sdk: flutter
  objectbox: ^1.4.0  

  build_runner: ^2.0.0
  objectbox_generator: ^1.4.0  

ObjectBox Store allows you to insert, query, update, and delete data.

final userBox = store.box<User>();
final user = User(name: 'John Doe');

final users = userBox.getAll();  

It allows for easy storage and retrieval of data in an object format, and supports complex queries and relationships. It is suitable for performance-critical real-time applications.

4. SharedPreferences

It is used to store simple key-value pairs and is suitable for managing settings or small amounts of data. Although its functionalities are limited compared to databases like Hive or SQLite, it is easy to use.

    sdk: flutter
  shared_preferences: ^2.0.5  

You can refer to an instance of SharedPreferences as shown below.

import 'package:shared_preferences/shared_preferences.dart';

Future<void> saveData() async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.setInt('counter', 10);  // 
  await prefs.setBool('repeat', true);  
  await prefs.setString('username', 'JohnDoe');   

Future<void> loadData() async {
  final prefs = await SharedPreferences.getInstance();
  int? counter = prefs.getInt('counter');  // 'counter' 
  bool? repeat = prefs.getBool('repeat');  // 'repeat' 
  String? username = prefs.getString('username');  // 'username' 

  print('Counter: $counter, Repeat: $repeat, Username: $username');

When storing small and simple pieces of data such as user preferences, settings, and login status, this is a useful feature. It is also useful for saving settings adjustments in the app, such as brightness and volume. Flutter Local Data Management

Flutter Local Data Management, Which One Is My Choice?

It’s important to choose the method that best suits the application’s requirements, considering the characteristics of each option!

In my case, I chose ‘SQLite’. I wanted to create a vocabulary app, but it wasn’t just a simple word-meaning pair; it also included various features such as favorites, sorting, hiding meanings, and a function to search in an English dictionary.

Initially, I ruled out SharedPreference because it handles simple key-value storage.

I also eliminated Vibe from the list. Vibe’s asynchronous database could facilitate real-time processing and large-scale operations, which is a benefit. However, I considered its disadvantage of sometimes not processing data consistently and immediately, potentially delivering delayed data, and excluded it from the list.

Ultimately, I deliberated between SQLite and ObjectBox.

SQLite uses SQL (Structured Query Language) to manipulate and query data, which is a strong advantage, and it also perfectly supports ACID (Atomicity, Consistency, Isolation, Durability) transactions. On the other hand, ObjectBox has a fast and simple API, but its queries and transactions are weak, so I finally chose SQLite.

*query : The process of requesting specific information from or issuing commands to a database***

ACID (Atomicity, Consistency, Isolation, Durability) The reason why this is important:

  • What is atomity?
    • The principle that transactions should be reflected in the database either all or none
    • All operations executed within a transaction should be processed as a single partitioned unit, with the transaction being committed if all operations complete successfully, and all operations being cancelled (rolled back) if any of them fail.
    • Maintain consistency of data by preventing partial operations from being performed
  • The benefits of ensuring data integrity, a reliable database system, effective error and parallel handling, and legal and regulatory compliance (a requirement for many platforms) make ACID a highly trusted database transaction.
Completed the SQLite installation ✅

Choosing the Right Flutter Local Data Management Method for Your Project

Choosing the right local data management method for your project can still be challenging even after reading this.

Follow these steps for an easier decision:

1. Assess Data Complexity

For simple data, consider SharedPreferences or Hive. If dealing with complex or relational data, think about SQLite or ObjectBox.

2. Consider Development Ease

Depending on the developer’s experience, integrating and using a specific database might be easier.

3. Performance Requirements

For large datasets or applications requiring quick response times, choose a performance-oriented database that uses NoSQL.

Other related sites and blogs

Persist data with SQLite

Leave a Comment