Hello there! We are about to explore an interesting fusion of two powerful tools: Flutter and Supabase. Flutter Supabase, as it's widely known, empowers us to build faster, more scalable and more secure applications. As developers, we always look for simplicity and believe me, Flutter Supabase gives us just that. I can't wait to walk you through how Flutter Supabase simplifies our work.
Firstly, let's get familiar with the concept of Flutter Supabase. Flutter, the open-source UI toolkit from Google, offers a seamless way to build cross-platform apps using a single programming language – Dart. Supabase, on the other hand, is an open-source Firebase alternative that provides backend services such as real-time databases, authentication, storage, function pipeline, and more.
Partnered together, they provide a quick yet effective method to handle the front-end and back-end requirements, thus forming the Flutter Supabase. The growing community support and extensive documents make Flutter Supabase a go-to choice for many developers.
Writing the same code for different platforms is a big challenge. That's why we appreciate Flutter, which addresses the critical pain points in cross-platform development. Now, combine this with Supabase, which simplifies back-end design, and voila— developing applications has never been easier. With Flutter Supabase, I can set up the major part of the infrastructure, from databases to user management, in a flash.
1 //main.dart 2 3 import 'package:flutter/material.dart'; 4 import 'package:supabase/supabase.dart'; 5 6 void main() { 7 // Initialize your Supabase project details 8 const supabaseUrl = "YOUR_SUPABASE_PROJECT_URL"; 9 const anonKey = "YOUR_SUPABASE_ANON_KEY"; 10 final client = SupabaseClient(supabaseUrl, anonKey); 11 12 // Run your Flutter App 13 runApp(MyApp()); 14 } 15 16 class MyApp extends StatelessWidget { 17 final SupabaseClient client; 18 19 MyApp({Key key, this.client}) : super(key: key); 20 21 @override 22 Widget build(BuildContext context) { 23 return MaterialApp( 24 title: 'Flutter Supabase Demo', 25 home: HomePage(client), 26 ); 27 } 28 } 29 30 // Your app's HomePage 31 class HomePage extends StatelessWidget { 32 final SupabaseClient client; 33 34 HomePage(this.client); 35 36 @override 37 Widget build(BuildContext context) { 38 return Scaffold( 39 appBar: AppBar( 40 title: Text('Welcome to Flutter Supabase!'), 41 ), 42 body: Center( 43 child: Text('Ready to embrace Flutter Supabase magic?'), 44 ), 45 ); 46 } 47 } 48
The above snippet is a basic setup of a Flutter Supabase application. You just have to replace the supabaseUrl and anonKey with your own Supabase project details. This code establishes a connection between our Flutter app and the Supabase backend, providing us with the power to utilize all of Supabase's features directly in our Flutter app.
As developers, we know that Flutter is a robust UI toolkit created by Google to help us build beautiful, natively compiled applications for mobile, web, and desktop platforms from a single codebase. When talking about its history, it was first announced in 2015 and later released in December 2018. The unique set of features and advantages, like the hot reload feature and "everything is a widget" approach, make it a popular choice among developers.
The conception of Flutter dates back to 2015, with its first live demonstration at Dart Developer Summit. Released to the public in December 2018, Flutter has since been thriving on its promise of a single codebase for both Android and iOS apps. Its Version 2.0, a milestone in itself, introduced stable web support, sound null safety, and the capability of creating desktop applications.
The beauty of Flutter lies in its features:
Now let's talk about the other half: Supabase itself.
Supabase started its journey in 2020 as an open-source alternative to Google's Firebase. It offers a collection of tools and services that developers can use to build and scale their applications. With its launch, developers got a solution that doesn't lock them into a proprietary ecosystem, providing both flexibility and control in managing and operating applications.
Supabase impresses with features like:
Real-time database: This means you can listen to database changes and immediately update your application without needing to refresh or poll.
User Authentication: It supports common sign-in methods, including social sign-ins.
Storage capabilities for storing files like images, videos, or documents.
Effective table management, including creating tables and defining schemas.
Most importantly, as an open-source tool, it aligns perfectly with the ethos of an ever-growing and evolving community.
Let's initiate our journey with the installation of Flutter and Supabase. The installation process is straightforward, but we'll walk through it step by step to ensure a smooth setup.
Installing Flutter primarily involves downloading the software and adding it to your system path for easy command-line access.
The installation process includes the following:
A flutter run command in the terminal, inside your project directory, gets your application up and running.
Let's dive into the installation of the Supabase client. In the Flutter Supabase blend, you already have Flutter installed.
Configuring Supabase for your Flutter project requires a ready Flutter project and an active Supabase project.
Step 1: Create a Supabase project on the Supabase website.
Step 2: Note down the generated Supabase URL and the anon key for client-side configurations.
Step 3: In your Flutter project, add the Supabase client in the pubspec.yaml file.
1 dependencies: 2 flutter: 3 sdk: flutter 4 supabase: ^1.10.0 5
Step 4: Run flutter packages get or flutter pub get to fetch the packages, and you are all set.
Integration of Supabase with your Flutter application is a straightforward process. But before we dive into that, let's first understand why we need the Supabase plugin for Flutter.
The supabase_flutter for Flutter is a client-side library that helps you interact with your Supabase backend seamlessly. The library offers various features, such as querying your database, managing users, working with file storage, and listening to real-time changes in your database.
The Supabase plugin offers the following benefits:
Now, let's move on to the integration process.
We start by initializing the Supabase client. We then pass it through all the widgets that require database interaction. Let's go through this step-by-step integration of Supabase with Flutter:
1 // Initialize your Supabase project details 2 const String supabaseUrl = "YOUR_SUPABASE_PROJECT_URL"; 3 const String anonKey = "YOUR_SUPABASE_ANON_KEY"; 4 5 // Create a single instance of the Supabase client 6 final SupabaseClient supabase = SupabaseClient(supabaseUrl, anonKey); 7 8 void main() { 9 runApp(MyApp()); 10 } 11 12 class MyApp extends StatelessWidget { 13 @override 14 Widget build(BuildContext context) { 15 return MaterialApp( 16 title: 'Flutter Supabase Sample', 17 home: HomePage(supabase), 18 ); 19 } 20 } 21 22 class HomePage extends StatelessWidget { 23 final SupabaseClient supabase; 24 25 HomePage(this.supabase); 26 27 ... 28 } 29
In the above code, after importing the respective packages, we initialize the Supabase client using the Supabase project URL and public anon key as the parameters. We then pass this client throughout the app to utilize the data from our Supabase backend.
Authentication is a key aspect of most applications today, and Flutter Supabase takes care of this beautifully. Supabase provides a built-in authentication system that supports various ways of logging in, including email-password and multiple OAuth providers. In this section, let's focus on how to handle authentication in your Flutter Supabase applications.
Supabase Auth is a secure and easy-to-use service for managing users. It handles tasks like sign-up, login, password recovery, and third-party logins. To authenticate a user in our Flutter Supabase application, we can simply use the Supabase client.
Let's integrate authentication into our Flutter app. Here's a simple example where we create a login function:
1 Future<void> login(String email, String password) async { 2 final response = await supabase.auth.signIn(email: email, password: password); 3 4 if (response.error != null) { 5 print('Login failed: ${response.error.message}'); 6 } else { 7 print('Login successful'); 8 } 9 } 10
This function takes an email and password, then uses the signIn method provided by the Supabase client to authenticate the user. If the process fails, we log an error message; otherwise, we log that the login was successful.
A brief example of creating new users using Supabase authentication would look like:
1 Future<void> signUp(String email, String password) async { 2 final response = await supabase.auth.signUp(email: email, password: password); 3 4 if (response.error != null) { 5 print('Sign Up failed: ${response.error.message}'); 6 } else { 7 print('User registered with Email..'); 8 } 9 } 10
To see how a simple login page would look using these functions in our Flutter Supabase application, let's consider the following:
1 class LoginPage extends StatelessWidget { 2 final emailController = TextEditingController(); 3 final passwordController = TextEditingController(); 4 5 Future<void> login(BuildContext context) async { 6 final email = emailController.text; 7 final password = passwordController.text; 8 9 final response = await supabase.auth.signIn(email: email, password: password); 10 if (response.error != null) { 11 ScaffoldMessenger.of(context) 12 .showSnackBar(SnackBar(content: Text('Login failed: ${response.error.message}'))); 13 } else { 14 ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Login successful'))); 15 } 16 } 17 18 @override 19 Widget build(BuildContext context) { 20 return Scaffold( 21 appBar: AppBar(title: const Text('Supabase Authentication')), 22 body: Padding( 23 padding: const EdgeInsets.fromLTRB(32, 128, 32, 32), 24 child: Column( 25 children: [ 26 TextField( 27 controller: emailController, 28 decoration: const InputDecoration(labelText: 'Email'), 29 ), 30 TextField( 31 controller: passwordController, 32 decoration: const InputDecoration(labelText: 'Password'), 33 obscureText: true, 34 ), 35 ElevatedButton( 36 child: const Text('Log in'), 37 onPressed: () => login(context), 38 ), 39 ], 40 ), 41 ), 42 ); 43 } 44 } 45
Now, let's discuss how we can handle different authentication states in our Flutter Supabase application.
Supabase provides two ways to handle changes in the authentication state:
Let's move on to how we can implement social login with Supabase Auth in your Flutter apps.
Adding a social login feature to your Flutter Supabase app is very simple. With Supabase Auth, you can provide your users with the convenience of using their existing Google, Facebook, or Github accounts to log into your application. For the sake of our discussion, let's focus on Google.
To implement Google login, you'll need to have a project configured in the Google Cloud Console with OAuth consent screen set up.
You wire the 'Sign in with Google button in your app to call the signIn() method with a Provider.google parameter:
1 Future<void> googleSignIn() async { 2 final response = await supabase.auth.signIn(provider: Provider.google); 3 4 if (response.error != null) { 5 print('Google sign in failed: ${response.error.message}'); 6 } else { 7 print('Google sign in successful'); 8 } 9 } 10
In the snippet above, the Provider.google parameter directs the Supabase client to authenticate using Google OAuth.
Now, whenever a user clicks on 'Sign in with Google', this convenient functionality is ready to go. But remember, in order to get this working, you must add your Supabase URL to the Authorized Redirect URIs list in your Google Cloud Console.
Querying data is an essential part of any application, and Supabase offers a succinct and powerful API for this. Let's understand how we can integrate Supabase query with our Flutter app and perform CRUD operations.
At its core, Supabase Query is a seamless way to interact with our Postgres database. It offers a simple yet potent API to perform various operations on our database. It provides methods for filtering, sorting, retrieving, updating, and deleting data, along with much more.
As we covered earlier, Supabase supports all standard CRUD operations. Let's understand each operation with the help of examples:
Create:To insert a new row into a table, we use the insert() method.
1 final response = await supabase 2 .from('tablename') 3 .insert({'column1': 'value1', 'column2': 'value2'}).execute(); 4
Read: To fetch data from our database, we use the select() method.
1 final response = await supabase 2 .from('tablename') 3 .select('column1, column2') 4 .execute(); 5
Update: To update existing data, we use the update() method.
1 final response = await supabase 2 .from('tablename') 3 .update({'column': 'new value'}) 4 .eq('id', 'row id') 5 .execute(); 6
Delete: To delete data from our table, we use the delete() method.
1 final response = await supabase 2 .from('tablename') 3 .delete() 4 .match({'id': 'row id'}) 5 .execute(); 6
Suppose we have a table called "tasks" which has three columns: 'id', 'title', and 'is_completed'. Now let's see how we can perform CRUD operations on this table:
1 // Insert a new task 2 void addNewTask(String title) async { 3 final response = await supabase 4 .from('tasks') 5 .insert({'title': title, 'is_completed': false}).execute(); 6 7 if (response.error != null) { 8 print('Adding task failed: ${response.error.message}'); 9 } else { 10 print('Task added successfully'); 11 } 12 } 13 // Fetch existing tasks 14 Future<void> fetchTasks() async { 15 final response = await supabase.from('tasks').select().execute(); 16 17 if (response.error != null) { 18 print('Fetching task failed: ${response.error.message}'); 19 } else { 20 // Handling fetched tasks 21 } 22 } 23 // Update task status 24 void updateTaskStatus(int taskId, bool isCompleted) async { 25 final response = await supabase 26 .from('tasks') 27 .update({'is_completed': isCompleted}).eq('id', taskId).execute(); 28 29 if (response.error != null) { 30 print('Updating task failed: ${response.error.message}'); 31 } else { 32 print('Task updated successfully'); 33 } 34 } 35 // Delete a task 36 void deleteTask(int taskId) async { 37 final response = await supabase.from('tasks').delete().eq('id', taskId).execute(); 38 39 if (response.error != null) { 40 print('Deleting task failed: ${response.error.message}'); 41 } else { 42 print('Task deleted successfully'); 43 } 44 } 45
Another powerful feature that Supabase provides is the ability to listen to real-time changes in your database. Let's illustrate this with a simple example. Consider a basic to-do list app. When a user marks a to-do item as completed, all the other connected users should see this change without refreshing or pulling down on their screen. This can be achieved by listening to real-time database changes.
So, how do we set this up in Flutter Supabase? Here's an example:
1 // Inside the init method or any such setup method 2 void initState() { 3 setupSupabaseRealtimeSubscription(); 4 super.initState(); 5 } 6 7 void setupSupabaseRealtimeSubscription() { 8 supabase 9 .from('todo_items') 10 .on(SupabaseEventTypes.all, (payload) { 11 print('Realtime update received: ${payload.eventType}'); 12 // Do something when there's a realtime update 13 }) 14 .subscribe(); 15 } 16
In this piece of code, we subscribe to the 'todo_items' table with all event types. When an event like INSERT, UPDATE, or DELETE occurs, we print the event type to the console. Of course, based on your requirements, you can replace the print statement to refresh your local data representation or update the UI.
This ability to listen to real-time changes in your database and immediately reflect the changes in the user application defines the modern, immersive, and collaborative experiences that users expect.
Working with Flutter Supabase, you'll come to appreciate how easy it is to manage real-time database updates and provide users with an interactive and responsive application.
Managing a database is an essential part of any application. One of the many advantages of using Supabase with Flutter is having a robust yet flexible database management system at your fingertips. In this section, we will dive into how you can effectively manage your database using Flutter Supabase.
Security is one of the crucial aspects when dealing with data. Supabase offers Role-Level Security (RLS), meaning you can control who can access or modify data based on the user's role.
RLS involves writing some security rules for your database tables that check the current user's role or any other characteristic before allowing operations on the affected rows. These rules are written using SQL and defined in the Supabase dashboard.
Here's an example:
1 create policy "Individuals can update own profile" on public.profiles 2 for update using ( 3 auth.role() = 'authenticated' and 4 auth.uid() = id) -- 'id' would be the name of your column that contains the user ID 5 with check ( 6 auth.role() = 'authenticated' and 7 auth.uid() = id); -- the check clause will make sure the user can only modify their own rows 8
These rules protect your users and their data, preventing unauthorized access and changes.
Regular database maintenance is crucial for keeping your application running smoothly. Here are some general maintenance practices:
That's it for basic database management with Flutter Supabase.
By now, we've learned about Flutter Supabase and its basic features. But there's so much more that Flutter Supabase offers. Let's explore some of these advanced features and how to use them in your Flutter applications.
Handling files is a common requirement for many applications. Supabase provides a Storage API that allows you to handle user-generated content like photos, audio, and video with ease. Here's an example of how you might use it:
1 void uploadFile() async { 2 final file = html.File([''], 'my_file.txt'); 3 final response = await supabase.storage.from('bucket').upload('path/to/file', file); 4 5 if (response.error != null) { 6 print('File upload failed: ${response.error.message}'); 7 } else { 8 print('File uploaded successfully'); 9 } 10 } 11
Push notifications are an excellent way to engage with your users and notify them about updates or messages when they're not actively using your app. With Flutter Supabase, you can send notifications to your users by integrating a third-party service like Firebase Cloud Messaging or OneSignal.
Lately, serverless functions have become quite popular, as they allow us to run backend code without managing the server. With Supabase, you can run serverless functions right from your Flutter application using 'Stored Procedures' and 'Triggers'.
Stored Procedures are a set of SQL statements that are stored in a database system. You can define a Stored Procedure in your Postgres database and invoke it from your Flutter Supabase application as part of a query.
Triggers are database operations that are automatically performed when a specified database event occurs.
Getting a sense of how developers apply Flutter Supabase in real-world projects can be super helpful. Case studies offer clear, practical examples of how this powerful technology combo works in diverse scenarios. Here, we'll examine two hypothetical case studies demonstrating Flutter Supabase in action.
Let's consider an application task management system used by a software development company.
The company needs an app on multiple platforms (web, Android, and iOS) whereby project managers can assign tasks to developers, and developers can update their task status.
Building separate applications for each platform was a considerable challenge. Managing the databases for storing project and task details and handling registration and real-time updates were also proving problematic.
Flutter Supabase came to their rescue. With Flutter's cross-platform functionality, they could now build for all platforms from a single codebase. The Supabase integration offered a robust database solution with simple CRUD operations. The team used Supabase's real-time functionality to effortlessly update each user about task changes. User management and secure authentication were also made easy, thanks to Supabase Auth.
Now consider a social media application, where users can share photos, follow other user profiles, and interact with them.
This is a photo-sharing application, similar to Instagram, where users can share photos and explore feeds of photos from the people they follow.
The development team was struggling with setting up the necessary backend services, including user authentication, a real-time database to store images and user posts, and image storage.
Flutter Supabase provided a comprehensive solution. They used Flutter to develop an appealing, responsive UI that worked across several platforms. Supabase's built-in authentication enabled user sign-in, while its real-time databases made user interactions live and interactive. The storage utility handled image uploads easily, and Supabase-compatible libraries aided in the filtering of content based on user preferences.
These case studies provide insight into the practical applications of Flutter Supabase. Whether you are working on a small or complex project, Flutter Supabase can meet the demands with its powerful options and flexibility.
Flutter Supabase marks a revolution in rapid application development. The combination of Flutter's cross-platform capabilities with Supabase's user-friendly and feature-rich backend services forms an impressive toolkit for developers. Throughout this post, we unpuzzled various aspects of Flutter Supabase — from the basics to advanced features, including the Flutter Supabase Authentication feature and implementing Supabase query in our Flutter apps.
We explored how the installation of Flutter and Supabase, integrating the two, and using the Supabase client for database operations and authentication processes define a new level of ease for developers. We also touched base on securing databases, good practices for database maintenance, using serverless functions, and more.
Case studies further testified to the versatility of Flutter Supabase, reinforcing that whether it's a task management system or a social media app, Flutter Supabase stands out as a go-to technology choice.
The future appears promising for Flutter Supabase. Envision creating a high-quality, high-performance application with an enjoyable development process and reduced go-to-market time. That's the power of Flutter Supabase. With a growing community and continuous improvements, we are likely only scratching the surface of what's possible with this amazing duo.
I hope you found this comprehensive guide enlightening and that it inspires you to explore and invent with Flutter Supabase. Enjoy coding!
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.