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.
Get Started
To get set up and prepped for the course:
- Get the source code on GitHub. It contains the starting base that we build upon in the course
- Create a Supabase account or spin up a Docker instance. This is a necessary first step to create our Supabase project
- 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:
supabase_flutter
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 {
WidgetsFlutterBinding.ensureInitialized();
await Supabase.initialize(
url: 'SUPABASE_URL',
anonKey: 'SUPABASE_ANON_KEY',
);
runApp(MyApp());
}
Initialising Supabase successfully gives you access to the SupabaseClient
object by doing the following:
final supabase = Supabase.instance.client;
flutter_riverpod
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';
@riverpod
MemoryRepository memoryRepository(MemoryRepositoryRef _) => MemoryRepository();
class MemoryRepository {
final _client = Supabase.instance.client;
Future getMemories() async {
return _client.from('memories').select('id, title, image_id')
.order('created_at');
}
}
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';
@riverpod
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.
Originally published at https://creativebracket.com
Top comments (0)