Dart Reference v1.0

Upgrade guide

supabase-flutter focuses on improving the developer experience and making it easier to use. This guide demonstrates how to upgrade from supabase-flutter v0 to v1.

Upgrade the client library

Update the package in your pubspec.yaml file.


_10
supabase_flutter: ^1.0.0

Error handling

The way supabase-flutter throws error has changed in v1. In v0, errors were returned as a response. In v1, errors are thrown as exceptions. This makes it more intuitive as a Flutter developer to handle errors.


_10
final res = await supabase.from('my_table').select().execute();
_10
final error = res.error;
_10
if (error != null) {
_10
// handle error
_10
}
_10
final data = res.data;

Auth classes and methods

Usage of SupabaseAuthState and SupabaseAuthRequiredState classes

In v0, SupabaseAuthState and SupabaseAuthRequiredState were required to handle automatic token refresh and to listen to auth state change. In v1, SupabaseAuthState and SupabaseAuthRequiredState are deprecated, and token refresh will happen automatically just by initializing Supabase. onAuthStateChange can be used to action on auth state change.


_15
await Supabase.initialize(
_15
url: 'SUPABASE_URL',
_15
anonKey: 'SUPABASE_ANON_KEY',
_15
);
_15
...
_15
_15
class AuthState<T extends StatefulWidget> extends SupabaseAuthState<T> {
_15
...
_15
}
_15
_15
...
_15
_15
class AuthRequiredState<T extends StatefulWidget> extends SupabaseAuthState<T> {
_15
...
_15
}

Listening to auth state change

onAuthStateChange now returns a Stream.


_10
final authSubscription = supabase.auth.onAuthStateChange((event, session) {
_10
// handle auth state change
_10
});
_10
_10
// Unsubscribe when no longer needed
_10
authSubscription.data?.unsubscribe();

Sign in with email and password

signIn() has been deprecated in favor of more explicit method signatures to help with type hinting. Previously it was difficult for developers to know what they were missing (e.g., a lot of developers didn't realize they could use passwordless magic links).


_10
await supabase.auth.signIn(email: email, password: password);


_10
await supabase.auth.signIn(email: email);

Sign in with a third-party OAuth provider


_10
await supabase.auth.signInWithProvider(
_10
Provider.github,
_10
options: AuthOptions(
_10
redirectTo: kIsWeb
_10
? null
_10
: 'io.supabase.flutter://reset-callback/'),
_10
);

Sign in with phone


_10
await supabase.auth.signIn(
_10
phone: '+13334445555',
_10
password: 'example-password',
_10
);

Sign in with phone using OTP


_10
final res = await supabase.auth.signIn(phone: phone);

Reset password for email


_10
await supabase.auth.api.resetPasswordForEmail(
_10
email,
_10
options:
_10
AuthOptions(redirectTo: 'io.supabase.flutter://reset-callback/'),
_10
);

Get the user's current session


_10
final session = supabase.auth.session();

Get the logged-in user


_10
final user = supabase.auth.user();

Update user data for a logged-in user


_10
await supabase.auth.update(
_10
UserAttributes(data: {'hello': 'world'})
_10
);

Data methods

.insert() / .upsert() / .update() / .delete() no longer return rows by default. Previously, these methods return inserted/updated/deleted rows by default (which caused some confusion), and you can opt to not return it by specifying returning: 'minimal'. Now the default behavior is to not return rows. To return inserted/updated/deleted rows, add a .select() call at the end.

Also, calling .execute() at the end of the query was a requirement in v0, but deprecated in v1.

Insert without returning inserted data


_10
await supabase
_10
.from('my_table')
_10
.insert(data, returning: ReturningOption.minimal)
_10
.execute();

Insert with returning inserted data


_10
final res = await supabase
_10
.from('my_table')
_10
.insert(data)
_10
.execute();

Realtime methods

Stream

.stream() no longer needs the .execute() at the end. Also, filtering by eq is a lot easier now. primaryKey is now a named parameter to make it more obvious what to pass.


_10
supabase.from('my_table:id=eq.120')
_10
.stream(['id'])
_10
.listen();

Subscribe


_10
final subscription = supabase
_10
.from('countries')
_10
.on(SupabaseEventTypes.all, (payload) {
_10
// Handle realtime payload
_10
})
_10
.subscribe();

Unsubscribe


_10
supabase.removeSubscription(subscription);