Storing Data in SQLite database in Flutter

Haider Ali
Complete Flutter Guide
3 min readJun 4, 2024

In Flutter apps we need persistent data storage. This means storing data/information within the app itself, even when the app is closed or the device is turned off. Here’s where SQLite comes in.

What is SQLite?

SQLite is a lightweight relational database management system (RDBMS) that’s embedded within the application.

Why Use SQLite in Flutter?

Here are some key benefits of using SQLite with Flutter:

  • Lightweight and Fast: SQLite boasts a small footprint and efficient performance, perfect for mobile apps where resources are limited.
  • Serverless and Easy to Use: There’s no need to set up or manage a separate server. SQLite integrates seamlessly into your Flutter project.
  • Cross-Platform Compatibility: SQLite works across Android, iOS, and even web platforms where Flutter is applicable.

Getting Started with SQLite in Flutter

To leverage SQLite in your Flutter applications, you’ll utilize the popular sqflite package. This package provides a Dart API for interacting with the SQLite database. It offers functionalities for:

  • Creating and opening databases
  • Defining tables and columns
  • Performing CRUD operations (Create, Read, Update, Delete) on data
  • Querying the database to retrieve specific information

Step#1: Adding dependencies

In order to use SQLite in Flutter we need two dependencies i.e. sqflite and path. Add these dependencies in the pubspec.yaml file.

dependencies:
sqflite: ^2.3.3
path: ^1.9.0

Step#2: Create database_service.dart in lib/services directory

After adding dependencies we will create a Database Service in database_service.dart. The Database Service will provide the following services:

Create database

Create tables

Add/insert data in tables

Retrieve data from tables

Update data in tables

Delete data from tables

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

class DatabaseService {
static Database? db;

Future<Database> getDatabase() async {
final dbDirPath = await getDatabasesPath();
final dbPath = join(dbDirPath, "student_db.db");
final database = await openDatabase(
dbPath,
onCreate: (db, version) {
db.execute('''
CREATE TABLE students(reg_no TEXT, name TEXT NOT NULL, cell_no TEXT)
''');
},
version: 1
);
return database;
}

Future<Database> getDB() async {
if (db != null ) return db!;
db = await getDatabase();
return db!;
}

Future<void> addStudent(String reg_no, String name, cell_no) async {
final db = await getDB();

await db.insert(
"students",
{ "reg_no": reg_no,
"name": name,
"cell_no": cell_no
}
);
}

Future<List<Map>> getStudents() async {
final db = await getDB();
final data = await db.query("students");
for(var d in data) {
print(d);
}
return data;
}
}

Step-3: User interface for using Database Service (Adding and retrieving data from the SQLite database)

main.dart

import 'package:flutter/material.dart';
import 'package:sqlite_demo/services/database_service.dart';

void main() {
runApp(const MyApp());
}

class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}

class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
final databaseService = DatabaseService();
String? reg_no, name, cell_no;
TextEditingController tcRegNo = TextEditingController();
TextEditingController tcName = TextEditingController();
TextEditingController tcCellNo = TextEditingController();

@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
TextField(
decoration: InputDecoration(hintText: "Reg. No."),
controller: tcRegNo,
),
TextField(
decoration: InputDecoration(hintText: "Name"),
controller: tcName,
),
TextField(
decoration: InputDecoration(hintText: "Cell No"),
controller: tcCellNo,
),
ElevatedButton(onPressed: addRecord, child: Text("Save")),
ElevatedButton(onPressed: printData, child: Text("Print Data")),

]
),


);

}

void addRecord() async {
await databaseService.addStudent(tcRegNo.text, tcName.text, tcCellNo.text);
}

void printData() async {
await databaseService.getStudents();
}

Widget StudentsList() {
Future<List<Map<String, dynamic>>>? students;
students = dbService.getStudents();
return FutureBuilder<List<Map<String, dynamic>>>(
future: students,
builder: (context, snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data!.length,
itemBuilder: (context, index) {
final student = snapshot.data![index];
return ListTile(
title: Text(student['name']),
subtitle: Text('Reg No: ${student['reg_no']}, Cell No: ${student['cell_no']}'),
);
},
);
} else if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
}
return Center(child: CircularProgressIndicator());
},
);
}


}

In the second video I will explain how to retrieve records from SQLite database table and display it in ListView in Flutter.

--

--