Integrating Flutter with Supabase: A Comprehensive Guide

Haris Bin Nasir Avatar

·

·

When it comes to building real-time apps with Flutter, using a backend service like Supabase can significantly simplify the process. Supabase is an open-source Firebase alternative that offers real-time databases, authentication, and storage features. With Supabase, developers can quickly set up a backend for their Flutter applications, enabling features like user authentication, database management, and more. This guide will walk you through how to set up and use Supabase with Flutter for building modern, scalable applications.

What is Supabase?

Supabase is an open-source backend-as-a-service (BaaS) that provides an easy-to-use platform for building full-featured applications. It’s built on PostgreSQL, allowing you to take advantage of the robustness of SQL databases while offering real-time capabilities similar to Firebase.

Key Features of Supabase:

  1. PostgreSQL Database: A full-fledged relational database with real-time updates.
  2. Authentication: Provides built-in user authentication with email, password, and third-party providers like Google and GitHub.
  3. Storage: File storage system for handling images, videos, and other static assets.
  4. RESTful API: Automatically generated RESTful API for your database schema.
  5. Real-Time Data: Real-time data synchronization with websockets, ensuring live updates in your app.

Setting Up Supabase for Flutter

To start using Supabase in your Flutter project, you’ll first need to create a Supabase account and set up your project.

Step 1: Create a Supabase Account

  1. Visit the Supabase website and sign up for a free account.
  2. Once logged in, create a new project and choose a database region.
  3. You’ll be provided with an API URL and a public API key, which you’ll use to integrate with your Flutter app.

Integrating Supabase with Flutter

Step 2: Set Up Flutter Project

  1. Create a New Flutter Project: If you don’t already have a Flutter project, you can create one by running:bashCopy codeflutter create my_supabase_app
  2. Add Supabase Flutter SDK: To integrate Supabase into your Flutter app, add the Supabase Flutter package by updating your pubspec.yaml file:yamlCopy codedependencies: flutter: sdk: flutter supabase_flutter: ^0.5.0 # Check the latest version on pub.dev Then, run:bashCopy codeflutter pub get
  3. Initialize Supabase: Initialize Supabase in your app by adding the API URL and public API key to your main Dart file.

Example of Initializing Supabase:

import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Initialize Supabase with API URL and Key
  await Supabase.initialize(
    url: 'https://your-supabase-api-url',
    anonKey: 'your-public-api-key',
  );

  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Supabase App',
      home: HomePage(),
    );
  }
}

Explanation:

  • Supabase Initialization: The Supabase.initialize() method initializes the connection to your Supabase project using the provided API URL and anonymous key.
  • HomePage: The HomePage widget will serve as the landing page of your Flutter app.

Setting Up Authentication with Supabase

One of Supabase’s standout features is its built-in authentication system. It supports traditional email/password authentication as well as third-party providers like Google and GitHub.

Step 3: Implementing User Authentication

To implement user authentication in Flutter, you can use Supabase’s built-in authentication methods.

Example of Email/Password Sign-Up:

import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

class AuthPage extends StatefulWidget {
  @override
  _AuthPageState createState() => _AuthPageState();
}

class _AuthPageState extends State<AuthPage> {
  final SupabaseClient client = Supabase.instance.client;
  final TextEditingController _emailController = TextEditingController();
  final TextEditingController _passwordController = TextEditingController();

  Future<void> signUp() async {
    final response = await client.auth.signUp(
      _emailController.text,
      _passwordController.text,
    );

    if (response.error != null) {
      print('Error: ${response.error!.message}');
    } else {
      print('Sign-Up Successful!');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Sign Up')),
      body: Column(
        children: [
          TextField(
            controller: _emailController,
            decoration: InputDecoration(labelText: 'Email'),
          ),
          TextField(
            controller: _passwordController,
            decoration: InputDecoration(labelText: 'Password'),
            obscureText: true,
          ),
          ElevatedButton(
            onPressed: signUp,
            child: Text('Sign Up'),
          ),
        ],
      ),
    );
  }
}

Explanation:

  • Supabase Authentication: This example demonstrates how to implement a simple email/password sign-up using Supabase’s authentication API.
  • Error Handling: If there’s an error (such as an invalid email or password), it will be displayed in the console.

Working with Real-Time Data in Supabase

Supabase provides real-time database synchronization using websockets. This allows your Flutter app to receive live updates when data changes in the database.

Step 4: Listening to Real-Time Data

To listen to real-time changes in your Supabase database, you can use the SupabaseRealtime feature.

Example of Real-Time Data:

import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

class RealTimePage extends StatefulWidget {
  @override
  _RealTimePageState createState() => _RealTimePageState();
}

class _RealTimePageState extends State<RealTimePage> {
  final SupabaseClient client = Supabase.instance.client;

  @override
  void initState() {
    super.initState();

    // Listening to real-time changes in the 'messages' table
    client
        .from('messages')
        .on(SupabaseEventTypes.insert, (payload) {
          print('New message: ${payload.newRecord}');
        })
        .subscribe();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Real-Time Messages')),
      body: Center(child: Text('Listening to real-time changes...')),
    );
  }
}

Explanation:

  • Real-Time Subscription: This example shows how to subscribe to real-time updates on a messages table in Supabase.
  • Handling Inserts: When a new record is inserted into the table, the app will receive a real-time update.

Storing Files with Supabase Storage

Supabase offers a file storage service that allows you to upload, download, and manage files such as images, videos, or documents.

Step 5: Uploading Files to Supabase Storage

You can use the SupabaseStorageClient to upload files directly from your Flutter app.

Example of File Upload:

import 'dart:io';
import 'package:image_picker/image_picker.dart';
import 'package:flutter/material.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

class UploadPage extends StatefulWidget {
  @override
  _UploadPageState createState() => _UploadPageState();
}

class _UploadPageState extends State<UploadPage> {
  final SupabaseClient client = Supabase.instance.client;
  File? _image;

  Future<void> pickImage() async {
    final image = await ImagePicker().pickImage(source: ImageSource.gallery);
    if (image != null) {
      setState(() {
        _image = File(image.path);
      });
      uploadImage(_image!);
    }
  }

  Future<void> uploadImage(File image) async {
    final response = await client.storage
        .from('uploads')
        .upload('public/${image.path.split('/').last}', image);

    if (response.error != null) {
      print('Error: ${response.error!.message}');
    } else {
      print('File Uploaded Successfully!');
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Upload Image')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            _image == null ? Text('No image selected') : Image.file(_image!),
            ElevatedButton(
              onPressed: pickImage,
              child: Text('Pick Image'),
            ),
          ],
        ),
      ),
    );
  }
}

Explanation:

  • Image Upload: This example demonstrates how to select an image from the gallery and upload it to Supabase storage.
  • Handling Files: You can manage your file uploads using Supabase’s storage API, making it easy to handle media files in your Flutter app.

Conclusion

By integrating Flutter with Supabase, you can leverage a powerful open-source backend that provides real-time data, authentication, storage, and more. Supabase offers an easy-to-use, feature-rich solution for developers who want to build scalable applications without complex setup. Whether you need real-time updates, user authentication, or file storage, Supabase can handle it all seamlessly within your Flutter app. For more detailed guides and advanced features, be sure to explore Supabase’s documentation and our upcoming tutorials.

Happy Coding…!!!

Leave a Reply

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