Hey there ๐, in this blog post, you will learn how to create and read the data in supabase using flutter packages (supabase_flutter).
If you understand Hindi ๐
Firstly, you need to set up supabase in a flutter. So for that, you need to read this ๐ article.
How to use supabase database in flutter || ๐ด Part โ 1
Step1: You need to make a table for the supabase database
Step2: Now you need to make a todo.dart file
import 'dart:convert'; | |
class Todo { | |
final int? | |
id; // we are keeping the id to be nullable because we will use Todo type object as argument in create function. | |
// So there, we will not pass any id but the supabase will automatically generate it for us. | |
final String title; | |
Todo({ | |
this.id, | |
required this.title, | |
}); | |
Todo copyWith({ | |
int? id, | |
String? title, | |
}) { | |
return Todo( | |
id: id ?? this.id, | |
title: title ?? this.title, | |
); | |
} | |
Map<String, dynamic> toMap() { | |
final result = <String, dynamic>{}; | |
if (id != null) { | |
result.addAll({'id': id}); | |
} | |
result.addAll({'title': title}); | |
return result; | |
} | |
factory Todo.fromMap(Map<String, dynamic> map) { | |
return Todo( | |
id: map['id']?.toInt(), | |
title: map['title'] ?? '', | |
); | |
} | |
String toJson() => json.encode(toMap()); | |
factory Todo.fromJson(String source) => Todo.fromMap(json.decode(source)); | |
@override | |
String toString() => 'Todo(id: $id, title: $title)'; | |
@override | |
bool operator ==(Object other) { | |
if (identical(this, other)) return true; | |
return other is Todo && other.id == id && other.title == title; | |
} | |
@override | |
int get hashCode => id.hashCode ^ title.hashCode; | |
} |
You can make models.dart file in the **model **folder.
export 'todo.dart';
Step3: Now, you need to make a supabase_data_manager.dartโ in the data folder in the utils folder. eg ๐
Now you can use this code ๐
import 'package:flutter_supabase_yt_1/models/models.dart'; // this is being used to import the todo.dart from models file. | |
import 'package:supabase_flutter/supabase_flutter.dart'; | |
class SupabaseDataManager { | |
// create function which takes one argument of Todo | |
Future<PostgrestResponse<dynamic>> createData(Todo todo) async { | |
PostgrestResponse<dynamic> res = await Supabase.instance.client | |
.from('todos') | |
// here ๐ you need to make todo.toMap() because we need to make Todo model to map --> eg Todo(title: 'This is first todo') -> {'title': 'This is first todo'} | |
.insert(todo.toMap()) | |
.execute(); | |
return res; | |
} | |
// read function | |
Future<PostgrestResponse<dynamic>> readData() async { | |
PostgrestResponse<dynamic> res = await Supabase.instance.client | |
.from('todos') | |
.select('id, title') | |
.execute(); | |
return res; | |
} | |
} | |
Then you can make a utils.dart file in the utils folder.
// from data
export 'data/supabase_data_manager.dart';
Now, you need to make a screens folder.
there are 3 files in the screens folder
Create Screen โ โcreate_screen.dartโ
Read Screen โ โread_screen.dartโ
-
screens.dart for exporting the above screens
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersimport 'package:flutter/material.dart'; import 'package:flutter_supabase_yt_1/models/models.dart'; import 'package:flutter_supabase_yt_1/utils/utils.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; class CreateScreen extends StatefulWidget { const CreateScreen({Key? key}) : super(key: key); @override State<CreateScreen> createState() => _CreateScreenState(); } class _CreateScreenState extends State<CreateScreen> { TextEditingController todoController = TextEditingController(); // instance SupabaseDataManager supabaseDataManager = SupabaseDataManager(); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Create')), body: Padding( padding: const EdgeInsets.all(20), child: Form( child: Column( children: [ TextFormField( // controller controller: todoController, decoration: const InputDecoration(hintText: 'Todo'), ), ElevatedButton(onPressed: _createdData, child: const Text('Create')) ], )), ), ); } Future _createdData() async { Todo todo = Todo(title: todoController.text); PostgrestResponse<dynamic> res = await supabaseDataManager.createData(todo); if (res.error != null) { // ignore: use_build_context_synchronously ScaffoldMessenger.of(context) .showSnackBar(SnackBar(content: Text(res.error!.message))); } // ignore: use_build_context_synchronously ScaffoldMessenger.of(context) .showSnackBar(SnackBar(content: Text('Created'))); } } This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersimport 'package:flutter/material.dart'; import 'package:flutter_supabase_yt_1/models/models.dart'; import 'package:flutter_supabase_yt_1/utils/utils.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; class ReadScreen extends StatelessWidget { const ReadScreen({Key? key}) : super(key: key); @override Widget build(BuildContext context) { List<Todo>? _todos; SupabaseDataManager supabaseDataManager = SupabaseDataManager(); Future<List<Todo>> readData() async { PostgrestResponse<dynamic> res = await supabaseDataManager.readData(); if (res.error != null) { throw Exception(res.error!.message); } // Todo --> [Todo(id: 1, title: 'This'),Todo(id: 2, title: 'fafdaf')] // Map --> [{'id' : 1, 'title': 'This'},{'id' : 2, 'title': 'adfafaf'}] return (res.data as List<dynamic>).map((e) => Todo.fromMap(e)).toList(); } return Scaffold( body: FutureBuilder( future: readData(), builder: ((context, snapshot) { if (snapshot.hasError) { return Center(child: Text(snapshot.error.toString())); } else if (snapshot.hasData) { return ListView.builder( itemCount: (snapshot.data! as List<Todo>).length, itemBuilder: ((BuildContext context, int index) { Todo todo = (snapshot.data! as List<Todo>)[index]; return ListTile( title: Text(todo.title), ); }), ); } // until the data has been loaded, we will see this progess indicator. return const Center(child: CircularProgressIndicator()); }), ), ); } }
export 'create_screen.dart'; | |
export 'read_screen.dart'; |
Now, you can switch the screens in the main. dart.
Example
import 'package:flutter/material.dart'; | |
import 'package:flutter_dotenv/flutter_dotenv.dart'; | |
import 'package:flutter_supabase_yt_1/screens/screens.dart'; | |
import 'package:supabase_flutter/supabase_flutter.dart'; | |
Future<void> main() async { | |
WidgetsFlutterBinding.ensureInitialized(); | |
// load env | |
await dotenv.load(); | |
// initialise the app | |
String supabaseBaseUrl = dotenv.env['SUPABASE_BASE_URL'] ?? ''; | |
String supabaseBaseKey = dotenv.env['SUPABASE_BASE_KEY'] ?? ''; | |
await Supabase.initialize(url: supabaseBaseUrl, anonKey: supabaseBaseKey); | |
runApp(const MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
const MyApp({Key? key}) : super(key: key); | |
// This widget is the root of your application. | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Flutter Demo', | |
theme: ThemeData( | |
primarySwatch: Colors.blue, | |
), | |
// you can place here CreateScreen() for viewing the create_screen screen | |
home: const ReadScreen(), | |
); | |
} | |
} |
Thanks for reading this blog. You can now try it out.
If you want to how to update and delete data ๐
If you have any questions, feel free to ask here ๐
Join the Next Dev Discord Server!
Top comments (0)