CRUD Operation With SQLite In Flutter

Here I don’t have to tell the worth of the Flutter cross-platform framework over and over. It is primarily for building Android and IOS applications with Dart. Could it be said that you are searching for a method for utilizing your Flutter project’s mobile device storage as a database? Simply integrating a SQLite package will do it for you. For all local SQL storage purposes, Flutter has presented the sqflite plugin. So we can accomplish all the nearby local storage-related capabilities through that plugin.
In this article, we will explore the CRUD Operation With SQLite In Flutter. We perceive how to execute a demo program. We will show you the simplest way to put away CRUD, create, update, read, and delete your data on the SQLite database utilizing sqflite package and provider state management. We will utilize an implanted SQLite database engine to store the database in Flutter Android and iOS in your Flutter applications.
For Sqflite:
sqflite 2.2.8+4 | Flutter Package
Flutter plugin for SQLite, a self-contained, high-reliability, embedded, SQL database engine.pub.dev
For path_provider:
path_provider | Flutter Package
Flutter plugin for getting commonly used locations on host platform file systems, such as the temp and app data…pub.dev
For Provider:
provider | Flutter Package
A wrapper around InheritedWidget to make them easier to use and more reusable.pub.dev
If you’re looking for the best Flutter app development company for your mobile application then feel free to contact us at — support@flutterdevs.com.
Table Of Contents::

Introduction:
This demo video shows how to perform a CRUD Operation With SQLite in Flutter and how CRUD Operation will work using the sqflite package and provider state management in your Flutter applications. We will show you the simplest way to store away CRUD, create, update, read, and delete your data on the SQLite database. It will be shown on your device.
Demo Module ::

Implementation:
Step 1: Add the dependencies
Add dependencies to pubspec — yaml file.
dependencies:
flutter:
sdk: flutter
sqflite: ^2.2.8+4
path_provider: ^2.1.1
provider: ^6.0.1
Step 2: Import
import 'package:signature/signature.dart';
Step 3: Run flutter packages get in the root directory of your app.
How to implement code in dart file :
You need to implement it in your code respectively:
Create a new dart file called user_model.dart
inside the lib
folder.
Create the user model which demonstrates the data structure that we want to manipulate inside the database. For this, we should create a class with the required properties and a method to map the data before inserting it into the database.
class UserModel {
int? id;
String name;
String email;
String desc;
UserModel({this.id, required this.name, required this.email, required this.desc});
Map<String, dynamic> toMap() {
return {
'id': id,
'name': name,
'email': email,
'desc': desc,
};
}
factory UserModel.fromMap(Map<String, dynamic> map) {
return UserModel(
id: map['id'],
name: map['name'],
email: map['email'],
desc: map['desc'],
);
}
}
Create a new dart file called database_helper.dart
inside the lib
folder.
Declare a function that uses imports to open a database connection. Use a user model class and create insertUser(), getUsers(), updateUser(), and deleteUser() functions.
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
import '../model/user_model.dart';
class DatabaseHelper {
Database? _database;
Future<Database?> get database async {
if (_database != null) return _database;
_database = await initDatabase();
return _database;
}
Future<Database> initDatabase() async {
String databasesPath = await getDatabasesPath();
String path = join(databasesPath, 'users.db');
return await openDatabase(path, version: 1, onCreate: _onCreate);
}
Future<void> _onCreate(Database db, int version) async {
await db.execute('''
CREATE TABLE users(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT,
email TEXT,
desc TEXT
)
''');
}
Future<int> insertUser(UserModel user) async {
Database? db = await database;
return await db!.insert('users', user.toMap());
}
Future<List<UserModel>> getUsers() async {
Database? db = await database;
List<Map<String, dynamic>> maps = await db!.query('users');
return List.generate(maps.length, (i) {
return UserModel.fromMap(maps[i]);
});
}
Future<int> updateUser(UserModel user) async {
Database? db = await database;
return await db!.update(
'users',
user.toMap(),
where: 'id = ?',
whereArgs: [user.id],
);
}
Future<int> deleteUser(int id) async {
Database? db = await database;
return await db!.delete('users', where: 'id = ?', whereArgs: [id]);
}
}
Create a new dart file called user_provider.dart
inside the lib
folder.
We will create the class UserProvider with ChangeNotifier and add it to the inside database function and also create loadUsers(), addUser(), updateUser(), and deleteUser() with notifyListeners().
import 'package:flutter/material.dart';
import 'package:flutter_sqlite_demo/database/database_helper.dart';
import 'package:flutter_sqlite_demo/model/user_model.dart';
class UserProvider with ChangeNotifier {
bool isLoading = false;
List<UserModel> _users = [];
final DatabaseHelper _databaseHelper = DatabaseHelper();
List<UserModel> get users => _users;
Future<void> loadUsers() async {
isLoading = true;
_users = await _databaseHelper.getUsers();
isLoading = false;
notifyListeners();
}
Future<void> addUser(UserModel user) async {
await _databaseHelper.insertUser(user);
notifyListeners();
}
Future<void> updateUser(UserModel user) async {
await _databaseHelper.updateUser(user);
notifyListeners();
}
Future<void> deleteUser(int id) async {
await _databaseHelper.deleteUser(id);
await loadUsers();
}
}
Create a new dart file called user_list_screen.dart
inside the lib
folder.
In this screen, we will show data when the user creates the data and then show a list of data on this screen. We will add the ListView.builder() method. In this method, we will add the itemCount and itemBuilder. In itemBuilder, we will add a ListTile widget. In this widget, we will add a title, on the subtitle we will add two texts, on the trailing we will add two icons delete, and edit icons.
Consumer<UserProvider>(builder: (context, userProvider, _) {
return userProvider.isLoading
? const Center(child: CircularProgressIndicator())
: userProvider.users.isEmpty
? const Center(
child: Text(
"Data Not Found",
style: TextStyle(fontSize: 18),
))
: Padding(
padding: const EdgeInsets.all(12.0),
child: ListView.builder(
itemCount: userProvider.users.length,
itemBuilder: (context, index) {
final user = userProvider.users[index];
return Card(
elevation: 3,
color: Colors.teal.shade300,
child: Padding(
padding: const EdgeInsets.all(12.0),
child: ListTile(
title: Padding(
padding: const EdgeInsets.only(bottom: 5.0),
child: Text(
user.name,
style: const TextStyle(
fontSize: 18, color: Colors.white),
),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
user.email,
style: const TextStyle(
fontSize: 18, color: Colors.white),
),
const SizedBox(
height: 5,
),
Text(
user.desc,
style: const TextStyle(
fontSize: 18, color: Colors.white),
),
],
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: const Icon(
Icons.edit,
color: Colors.black,
),
onPressed: () {
_navigateToEditUser(context, user);
},
),
IconButton(
icon: const Icon(Icons.delete,
color: Colors.black),
onPressed: () {
userProvider.deleteUser(user.id ?? 0);
},
),
],
),
),
),
);
},
),
);
})
When we run the application, we ought to get the screen’s output like the underneath screen capture.

Create a new dart file called create_user_screen.dart
inside the lib
folder.
In this screen, the user will create a database. The user fills in all the textformfield and presses the save button then the database creates and shows the data on UserListScreen().
import 'package:flutter/material.dart';
import 'package:flutter_sqlite_demo/database/database_helper.dart';
import 'package:flutter_sqlite_demo/model/user_model.dart';
import 'package:flutter_sqlite_demo/provider/user_provider.dart';
import 'package:flutter_sqlite_demo/screens/user_list_screen.dart';
import 'package:provider/provider.dart';
class CreateUserScreen extends StatefulWidget {
const CreateUserScreen({super.key});
@override
State<CreateUserScreen> createState() => _CreateUserScreenState();
}
class _CreateUserScreenState extends State<CreateUserScreen> {
final TextEditingController nameController = TextEditingController();
final TextEditingController emailController = TextEditingController();
final TextEditingController descController = TextEditingController();
final _formKey = GlobalKey<FormState>();
void _submitForm() async {
if (_formKey.currentState?.validate() ?? false) {
final user = UserModel(
name: nameController.text,
email: emailController.text,
desc: descController.text,
);
Provider.of<UserProvider>(context, listen: false).addUser(user);
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const UserListScreen(),),
);
nameController.clear();
emailController.clear();
descController.clear();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Create User'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
controller: nameController,
validator: (value) {
if (value?.isEmpty ?? true) {
return 'Please enter a name';
}
return null;
},
decoration: const InputDecoration(labelText: 'Name'),
),
TextFormField(
controller: emailController,
validator: (input) => !input!.contains('@')
? 'Please enter a valid email'
: null,
//onSaved: (input) => _email = input!,
decoration: const InputDecoration(labelText: 'Email'),
),
TextFormField(
controller: descController,
validator: (value) {
if (value?.isEmpty ?? true) {
return 'Please enter a description';
}
return null;
},
decoration: const InputDecoration(labelText: 'Desc'),
),
const SizedBox(height: 20.0),
ElevatedButton(
onPressed: _submitForm,
child: const Text('Save'),
),
],
),
),
),
);
}
}
When we run the application, we ought to get the screen’s output like the underneath screen capture.


Create a new dart file called edit_user_screen.dart
inside the lib
folder.
In this screen, the user will update the current data, save the new data from the database, and show the updated data on UserListScreen().
import 'package:flutter/material.dart';
import 'package:flutter_sqlite_demo/model/user_model.dart';
import 'package:flutter_sqlite_demo/provider/user_provider.dart';
import 'package:flutter_sqlite_demo/screens/user_list_screen.dart';
import 'package:provider/provider.dart';
class EditUserScreen extends StatefulWidget {
final UserModel user;
const EditUserScreen({super.key, required this.user});
@override
State<EditUserScreen> createState() => _EditUserScreenState();
}
class _EditUserScreenState extends State<EditUserScreen> {
final _formKey = GlobalKey<FormState>();
final nameController = TextEditingController();
final emailController = TextEditingController();
final descController = TextEditingController();
@override
void initState() {
super.initState();
nameController.text = widget.user.name;
emailController.text = widget.user.email;
descController.text = widget.user.desc;
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Edit User'),
),
body: Padding(
padding: const EdgeInsets.all(16.0),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
controller: nameController,
decoration: const InputDecoration(labelText: 'Name'),
validator: (value) {
if (value?.isEmpty ?? true) {
return 'Please enter a name';
}
return null;
},
),
TextFormField(
controller: emailController,
decoration: const InputDecoration(labelText: 'Email'),
validator: (input) =>
!input!.contains('@') ? 'Please enter a valid email' : null,
//onSaved: (input) => _email = input!,
),
TextFormField(
controller: descController,
decoration: const InputDecoration(labelText: 'Desc'),
validator: (value) {
if (value?.isEmpty ?? true) {
return 'Please enter a description';
}
return null;
},
),
const SizedBox(height: 20.0),
ElevatedButton(
onPressed: () {
if (_formKey.currentState?.validate() ?? false) {
final updatedUser = UserModel(
id: widget.user.id,
name: nameController.text,
email: emailController.text,
desc: descController.text,
);
Provider.of<UserProvider>(context, listen: false)
.updateUser(updatedUser);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const UserListScreen(),
),
);
}
},
child: const Text('Save'),
),
],
),
),
),
);
}
}
When we run the application, we ought to get the screen’s output like the underneath screen capture.

Code File:
import 'package:flutter/material.dart';
import 'package:flutter_sqlite_demo/model/user_model.dart';
import 'package:flutter_sqlite_demo/provider/user_provider.dart';
import 'package:flutter_sqlite_demo/screens/create_user_screen.dart';
import 'package:flutter_sqlite_demo/screens/edit_user_screen.dart';
import 'package:provider/provider.dart';
import '../app_constants.dart';
class UserListScreen extends StatefulWidget {
const UserListScreen({super.key});
@override
_UserListScreenState createState() => _UserListScreenState();
}
class _UserListScreenState extends State<UserListScreen> {
final userProvider =
Provider.of<UserProvider>(AppConstants.globalNavKey.currentContext!);
@override
void initState() {
// TODO: implement initState
userProvider.loadUsers();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
automaticallyImplyLeading: false,
title: const Text('User List'),
),
body: Consumer<UserProvider>(builder: (context, userProvider, _) {
return userProvider.isLoading
? const Center(child: CircularProgressIndicator())
: userProvider.users.isEmpty
? const Center(
child: Text(
"Data Not Found",
style: TextStyle(fontSize: 18),
))
: Padding(
padding: const EdgeInsets.all(12.0),
child: ListView.builder(
itemCount: userProvider.users.length,
itemBuilder: (context, index) {
final user = userProvider.users[index];
return Card(
elevation: 3,
color: Colors.teal.shade300,
child: Padding(
padding: const EdgeInsets.all(12.0),
child: ListTile(
title: Padding(
padding: const EdgeInsets.only(bottom: 5.0),
child: Text(
user.name,
style: const TextStyle(
fontSize: 18, color: Colors.white),
),
),
subtitle: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
user.email,
style: const TextStyle(
fontSize: 18, color: Colors.white),
),
const SizedBox(
height: 5,
),
Text(
user.desc,
style: const TextStyle(
fontSize: 18, color: Colors.white),
),
],
),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: const Icon(
Icons.edit,
color: Colors.black,
),
onPressed: () {
_navigateToEditUser(context, user);
},
),
IconButton(
icon: const Icon(Icons.delete,
color: Colors.black),
onPressed: () {
userProvider.deleteUser(user.id ?? 0);
},
),
],
),
),
),
);
},
),
);
}),
floatingActionButton: FloatingActionButton(
onPressed: () {
_navigateToCreateUser(context);
},
child: const Icon(Icons.add),
),
);
}
void _navigateToCreateUser(BuildContext context) async {
await Navigator.push(
context,
MaterialPageRoute(builder: (context) => const CreateUserScreen()),
);
setState(() {});
}
void _navigateToEditUser(BuildContext context, UserModel user) async {
await Navigator.push(
context,
MaterialPageRoute(builder: (context) => EditUserScreen(user: user)),
);
setusing firebaseState(() {});
}
}
Conclusion:
In the article, I have explained the CRUD Operation With SQLite In Flutter; you can modify this code according to your choice. This was a small introduction to the CRUD Operation With SQLite In Flutter User Interaction from my side, and it’s working using Flutter.
I hope this blog will provide you with sufficient information on Trying the CRUD Operation With SQLite in your Flutter projects. We will show you what the Introduction is. Make a demo program for working on CRUD Operation With SQLite in your Flutter applications. So please try it.
❤ ❤ Thanks for reading this article ❤❤
If I need to correct something? Let me know in the comments. I would love to improve.
Clap 👏 If this article helps you.
GitHub Link:
find the source code of the Flutter Sqlite Demo:
GitHub – flutter-devs/flutter_sqlite_demo
Contribute to flutter-devs/flutter_sqlite_demo development by creating an account on GitHub.github.com
Feel free to connect with us:
And read more articles from FlutterDevs.com.
FlutterDevs team of Flutter developers to build high-quality and functionally-rich apps. Hire a Flutter developer for your cross-platform Flutter mobile app project on an hourly or full-time basis as per your requirement! For any flutter-related queries, you can connect with us on Facebook, GitHub, Twitter, and LinkedIn.
We welcome feedback and hope that you share what you’re working on using #FlutterDevs. We truly enjoy seeing how you use Flutter to build beautiful, interactive web experiences.
