Creative Bracket

Supabase & Riverpod Minicourse | Build A Realtime Photo Sharing App

Let’s build a realtime photo sharing app with Supabase and Riverpod.

In this free minicourse, we will build a realtime photo sharing app with Supabase, Flutter and Riverpod. Supabase is an open-source Firebase alternative that offers a set of tools to create scalable and secure web and mobile applications.

Flutter is an open-source framework by Google for building natively compiled, multi-platform applications. The SDK is written in Dart which prides itself as being a flexible, general-purpose programming language which supports both AOT and JIT compilation targets.

On the other hand, Riverpod is a state management library for Flutter that provides a simple, composable way of managing application state. It uses dependency injection to enable sharing state across the app and offers an intuitive API for managing state.

Watch the minicourse

Get started

To get set up and prepped for the course:

  1. Get the source code on GitHub. It contains the starting base that we build upon in the course
  2. Create a Supabase account or spin up a Docker instance. This is a necessary first step to create our Supabase project
  3. Install the Flutter SDK. This is what weโ€™re building our app with ๐Ÿ”ฅ

Package Dependencies

There are several dependencies that are added to the project, though the important ones are:


This contains the client library for interacting with Supabase. Creating a Supabase account and project will expose a Project url as well as an API key. These will enable you to initialise Supabase by doing the following:

import 'package:supabase_flutter/supabase_flutter.dart';

void main() async {

  await Supabase.initialize(
    url: 'SUPABASE_URL',
    anonKey: 'SUPABASE_ANON_KEY',


Initialising Supabase successfully gives you access to the SupabaseClient objects by doing the following:

final supabase = Supabase.instance.client;


This allows using the riverpod state management solution in a Flutter project. We will be creating several Providers and Notifier instances via Code Generation, available via Riverpod 2+. 

Here is a snippet of how creating a Provider that exposes a Repository client looks like:

// file: memory_repository.dart

import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

part 'memory_repository.g.dart';

MemoryRepository memoryRepository(MemoryRepositoryRef _) => MemoryRepository();

class MemoryRepository {
  final _client = Supabase.instance.client;
  Future getMemories() async {
    return _client.from('memories').select('id, title, image_id')

Youโ€™ll then be able to generate the relevant AutoDisposeProvider<MemoryRepository> object by running the following:

$ flutter pub run build_runner build

When listening to authentication state changes, the StreamProvider<T> object is quite effective for sharing the Supabase authentication state:

// file: auth_user.dart

import 'package:riverpod_annotation/riverpod_annotation.dart';
import 'package:supabase_flutter/supabase_flutter.dart';

part 'auth_user.g.dart';

Stream<User?> authUser(AuthUserRef ref) async* {
  final authStream = Supabase.instance.client.auth.onAuthStateChange;

  await for (final authState in authStream) {
    yield authState.session?.user;

Watch full minicourse below ๐Ÿš€

Sharing is caring ๐Ÿค—

If you enjoyed reading this post, please share this through your social media channels. Also check out and subscribe to my YouTube channel (hit the bell icon too) for full-stack development tutorials on Dart and Flutter.

Subscribe to the newsletter for my free Get started with Dart eBook and to be notified when new content is released.

Like, share and follow me for more content on Dart.

Jermaine Oppong

Hello ๐Ÿ‘‹, I show programmers how to build full-stack web applications with the Dart SDK. I am passionate about teaching others, having received tremendous support on sites like and for my articles covering various aspects of the Dart language and ecosystem.

Useful learning materials