Flutter-8: Implementing Data Persistence

Welcome to the final post in our Flutter development series! In this article, we’ll explore how to permanently store and retrieve data in your app. This technique ensures that your user’s data is preserved even when they close and reopen the app.

1. What is Data Persistence?

Data persistence refers to the continuity of data after the app is closed or the device is powered off. It’s a crucial feature that significantly enhances user experience.

2. Methods of Implementing Data Persistence in Flutter

Flutter offers several ways to implement data persistence. In this post, we’ll focus on two of the most common and straightforward methods:

  1. SharedPreferences
  2. SQLite Database

3. Using SharedPreferences

SharedPreferences is ideal for storing simple key-value pairs of data.

3.1 Installing SharedPreferences

First, add the following dependency to your pubspec.yaml file:

dependencies:
  shared_preferences: ^2.0.12

Then run the following command in your terminal:

flutter pub get

3.2 SharedPreferences Usage Example

import 'package:shared_preferences/shared_preferences.dart';

// Saving data
Future<void> saveData() async {
  final prefs = await SharedPreferences.getInstance();
  await prefs.setString('username', 'FlutterDev');
  await prefs.setInt('age', 25);
  await prefs.setBool('isStudent', true);
}

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

  print('Username: $username');
  print('Age: $age');
  print('Is Student: $isStudent');
}

Code Explanation:

  1. SharedPreferences.getInstance(): This method retrieves an instance of SharedPreferences. We use ‘await’ because this operation is performed asynchronously.
  2. prefs.setString(), prefs.setInt(), prefs.setBool(): These methods store string, integer, and boolean values respectively. The first argument is the key, and the second is the value to be stored.
  3. prefs.getString(), prefs.getInt(), prefs.getBool(): These methods retrieve stored values. They take the key as an argument and return the corresponding value.
  4. String?, int?, bool?: The ‘?’ here is for null safety. It means these methods may return null if no value is stored for the given key.

4. Using SQLite Database

SQLite is suitable for storing more complex and structured data.

4.1 Installing sqflite Package

Add the following dependencies to your pubspec.yaml file:

dependencies:
  sqflite: ^2.0.0+4
  path: ^1.8.0

Then run in your terminal:

flutter pub get

4.2 SQLite Database Usage Example

import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';

class DatabaseHelper {
  static final DatabaseHelper instance = DatabaseHelper._init();
  static Database? _database;

  DatabaseHelper._init();

  Future<Database> get database async {
    if (_database != null) return _database!;
    _database = await _initDB('todo.db');
    return _database!;
  }

  Future<Database> _initDB(String filePath) async {
    final dbPath = await getDatabasesPath();
    final path = join(dbPath, filePath);
    return await openDatabase(path, version: 1, onCreate: _createDB);
  }

  Future _createDB(Database db, int version) async {
    await db.execute('''
      CREATE TABLE todos(
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        title TEXT,
        completed INTEGER
      )
    ''');
  }

  Future<int> insertTodo(Map<String, dynamic> todo) async {
    final db = await instance.database;
    return await db.insert('todos', todo);
  }

  Future<List<Map<String, dynamic>>> getTodos() async {
    final db = await instance.database;
    return await db.query('todos');
  }
}

// Usage example
void main() async {
  // Add a Todo
  await DatabaseHelper.instance.insertTodo({
    'title': 'Study Flutter',
    'completed': 0
  });

  // Retrieve Todos
  final todos = await DatabaseHelper.instance.getTodos();
  print(todos);
}

Code Explanation:

  1. DatabaseHelper: This class manages database operations. It uses the singleton pattern to ensure only one instance is created.
  2. _initDB(): This method creates or opens the database file and returns a database instance.
  3. _createDB(): This method is called when the database is first created. It creates the ‘todos’ table.
  4. insertTodo(): This method inserts a new todo item into the database. db.insert() returns the id of the inserted row.
  5. getTodos(): This method retrieves all todo items from the database. db.query() returns all rows in the table.
  6. Map<String, dynamic>: This represents a map where the key is a string and the value can be of any type. SQLite uses this format for data exchange.

5. Considerations When Implementing Data Persistence

  1. Encrypt sensitive information before storing.
  2. Use the file system for large volumes of data.
  3. Implement synchronization logic between local storage and network for data that requires network connectivity.

6. Related Resources

To learn more about data persistence in Flutter, check out these resources:

  1. Official Documentation:
  1. Tutorials and Guides:
  1. Video Resources:
  1. Blog Posts:
  1. Advanced Topics:
  1. Community Resources:

7. Conclusion

We’ve explored how to implement data persistence in Flutter. SharedPreferences is suitable for simple data, while SQLite is better for more complex data structures. Choose the method that best fits your app’s requirements.

Use the provided resources to further enhance your Flutter development skills. If you have any questions or feedback, feel free to leave a comment. Best of luck on your Flutter development journey!

Related Posts

Flutter development-1 – CSAI

Flutter Development-2: Project Creation and Structure Understanding – CSAI

Flutter Development-3: Implementing a To-Do List App UI – CSAI

Flutter Development-4: Adding App State Management – CSAI

Flutter Development-5: Adding Local Storage – CSAI

Flutter development-6: Enhancing UI and Features – CSAI

Leave a Reply

Your email address will not be published. Required fields are marked *