Skip to content
Dart Reference v2.0

Flutter Client Library

supabase_flutterView on GitHub

This reference documents every object and method available in Supabase's Flutter library, supabase-flutter. You can use supabase-flutter to interact with your Postgres database, listen to database changes, invoke Deno Edge Functions, build login and user management functionality, and manage large files.

We also provide a supabase package for non-Flutter projects.


Installing

Install from pub.dev#

You can install Supabase package from pub.dev

1
flutter pub add supabase_flutter

Enable Data API access#

supabase_flutter uses the Data API to query and mutate your Postgres data. You first need to grant Data API roles permissions to access your tables and functions.

In Data API integrations settings, expose the specific tables and functions you want to access. To automatically grant access for new tables and functions in public, enable Default privileges for new entities.

Alternatively, use SQL to grant the required permissions:

1
-- Before granting access to client roles, make sure RLS is enabled
2
-- and create the policies required for each role's allowed operations.
3
alter table public.your_table enable row level security;
4
-- create policy ... on public.your_table ...;
5
6
-- Grant least-privilege access to tables after RLS and policies are in place
7
grant select on public.your_table to anon;
8
grant select, insert, update, delete on public.your_table to authenticated;
9
grant all on public.your_table to service_role;
10
11
-- Grant execute on functions after verifying any table access they rely on
12
grant execute on function public.your_function to authenticated, service_role;

Initializing

You can initialize Supabase with the static initialize() method of the Supabase class.

The Supabase client is your entrypoint to the rest of the Supabase functionality and is the easiest way to interact with everything we offer within the Supabase ecosystem.

Parameters

  • url
    Required
    string

    The unique Supabase URL which is supplied when you create a new project in your project dashboard.

  • publishableKey
    Required
    string

    The publishable (anon) key supplied when you create a new project in your project dashboard. Use this for client-side apps. The deprecated anonKey parameter is still accepted but publishableKey takes precedence when both are supplied.

  • headers
    Optional
    Map<String, String>

    Custom header to be passed to the Supabase client.

  • httpClient
    Optional
    Client

    Custom http client to be used by the Supabase client.

  • authOptions
    Optional
    FlutterAuthClientOptions

    Options to change the Auth behaviors.

  • postgrestOptions
    Optional
    PostgrestClientOptions

    Options to change the Postgrest behaviors.

  • realtimeClientOptions
    Optional
    RealtimeClientOptions

    Options to change the Realtime behaviors.

  • storageOptions
    Optional
    StorageClientOptions

    Options to change the Storage behaviors.

1
Future<void> main() async {
2
await Supabase.initialize(
3
url: 'https://xyzcompany.supabase.co',
4
publishableKey: 'your-publishable-key',
5
);
6
7
runApp(MyApp());
8
}
9
10
// Get a reference your Supabase client
11
final supabase = Supabase.instance.client;

Upgrade guide

Although supabase_flutter v2 brings a few breaking changes, for the most part the public API should be the same with a few minor exceptions. We have brought numerous updates behind the scenes to make the SDK work more intuitively for Flutter and Dart developers.

Upgrade the client library#

Make sure you are using v2 of the client library in your pubspec.yaml file.

1
supabase_flutter: ^2.0.0

Optionally passing custom configuration to Supabase.initialize() is now organized into separate objects:

1
await Supabase.initialize(
2
url: supabaseUrl,
3
publishableKey: publishableKey,
4
authFlowType: AuthFlowType.pkce,
5
storageRetryAttempts: 10,
6
realtimeClientOptions: const RealtimeClientOptions(
7
logLevel: RealtimeLogLevel.info,
8
),
9
);

Auth updates#

Renaming Provider to OAuthProvider#

Provider enum is renamed to OAuthProvider. Previously the Provider symbol often collided with classes in the provider package and developers needed to add import prefixes to avoid collisions. With the new update, developers can use Supabase and Provider in the same codebase without any import prefixes.

1
await supabase.auth.signInWithOAuth(
2
Provider.google,
3
);

Sign in with Apple method deprecated#

We have removed the sign_in_with_apple dependency in v2. This is because not every developer needs to sign in with Apple, and we want to reduce the number of dependencies in the library.

With v2, you can import sign_in_with_apple as a separate dependency if you need to sign in with Apple. We have also added auth.generateRawNonce() method to easily generate a secure nonce.

1
await supabase.auth.signInWithApple();

Initialization does not await for session refresh#

In v1, Supabase.initialize() would await for the session to be refreshed before returning. This caused delays in the app's launch time, especially when the app is opened in a poor network environment.

In v2, Supabase.initialize() returns immediately after obtaining the session from the local storage, which makes the app launch faster. Because of this, there is no guarantee that the session is valid when the app starts.

If you need to make sure the session is valid, you can access the isExpired getter to check if the session is valid. If the session is expired, you can listen to the onAuthStateChange event and wait for a new tokenRefreshed event to be fired.

1
// Session is valid, no check required
2
final session = supabase.auth.currentSession;

Removing Flutter Webview dependency for OAuth sign in#

In v1, on iOS you could pass a BuildContext to the signInWithOAuth() method to launch the OAuth flow in a Flutter Webview.

In v2, we have dropped the webview_flutter dependency in v2 to allow you to have full control over the UI of the OAuth flow. We now have native support for Google and Apple sign in, so opening an external browser is no longer needed on iOS.

Because of this update, we no longer need the context parameter, so we have removed the context parameter from the signInWithOAuth() method.

1
// Opens a webview on iOS.
2
await supabase.auth.signInWithOAuth(
3
Provider.github,
4
authScreenLaunchMode: LaunchMode.inAppWebView,
5
context: context,
6
);

PKCE is the default auth flow type#

PKCE flow, which is a more secure method for obtaining sessions from deep links, is now the default auth flow for any authentication involving deep links.

1
await Supabase.initialize(
2
url: 'SUPABASE_URL',
3
publishableKey: 'SUPABASE_PUBLISHABLE_KEY',
4
authFlowType: AuthFlowType.implicit, // set to implicit by default
5
);

Auth callback host name parameter removed#

Supabase.initialize() no longer has the authCallbackUrlHostname parameter. The supabase_flutter SDK will automatically detect auth callback URLs and handle them internally.

1
await Supabase.initialize(
2
url: 'SUPABASE_URL',
3
publishableKey: 'SUPABASE_PUBLISHABLE_KEY',
4
authCallbackUrlHostname: 'auth-callback',
5
);

SupabaseAuth class removed#

The SupabaseAuth had an initialSession member, which was used to obtain the initial session upon app start. This is now removed, and currentSession should be used to access the session at any time.

1
// Use `initialSession` to obtain the initial session when the app starts.
2
final initialSession = await SupabaseAuth.initialSession;

Data methods#

Insert and return data#

We made the query builder immutable, which means you can reuse the same query object to chain multiple filters and get the expected outcome.

1
// If you declare a query and chain filters on it
2
final myQuery = supabase.from('my_table').select();
3
4
final foo = await myQuery.eq('some_col', 'foo');
5
6
// The `eq` filter above is applied in addition to the following filter
7
final bar = await myQuery.eq('another_col', 'bar');

Renaming is and in filter#

Because is and in are reserved keywords in Dart, v1 used is_ and in_ as query filter names. Users found the underscore confusing, so the query filters are now renamed to isFilter and inFilter.

1
final data = await supabase
2
.from('users')
3
.select()
4
.is_('status', null);
5
6
final data = await supabase
7
.from('users')
8
.select()
9
.in_('status', ['ONLINE', 'OFFLINE']);

Deprecate FetchOption in favor of count() and head() methods#

FetchOption() on .select() is now deprecated, and new .count() and head() methods are added to the query builder.

count() on .select() performs the select while also getting the count value, and .count() directly on .from() performs a head request resulting in only fetching the count value.

1
// Request with count option
2
final res = await supabase.from('cities').select(
3
'name',
4
const FetchOptions(
5
count: CountOption.exact,
6
),
7
);
8
9
final data = res.data;
10
final count = res.count;
11
12
// Request with count and head option
13
// obtains the count value without fetching the data.
14
final res = await supabase.from('cities').select(
15
'name',
16
const FetchOptions(
17
count: CountOption.exact,
18
head: true,
19
),
20
);
21
22
final count = res.count;

PostgREST error codes#

The PostgrestException instance thrown by the API methods has a code property. In v1, the code property contained the http status code.

In v2, the code property contains the PostgREST error code, which is more useful for debugging.

1
try {
2
await supabase.from('countries').select();
3
} on PostgrestException catch (error) {
4
error.code; // Contains http status code
5
}

Realtime methods#

Realtime methods contains the biggest breaking changes. Most of these changes are to make the interface more type safe.

We have removed the .on() method and replaced it with .onPostgresChanges(), .onBroadcast(), and three different presence methods.

Postgres Changes#

Use the new .onPostgresChanges() method to listen to realtime changes in the database.

In v1, filters were not strongly typed because they took a String type. In v2, filter takes an object. Its properties are strictly typed to catch type errors.

The payload of the callback is now typed as well. In v1, the payload was returned as dynamic. It is now returned as a PostgresChangePayload object. The object contains the oldRecord and newRecord properties for accessing the data before and after the change.

1
supabase.channel('my_channel').on(
2
RealtimeListenTypes.postgresChanges,
3
ChannelFilter(
4
event: '*',
5
schema: 'public',
6
table: 'messages',
7
filter: 'room_id=eq.200',
8
),
9
(dynamic payload, [ref]) {
10
final Map<String, dynamic> newRecord = payload['new'];
11
final Map<String, dynamic> oldRecord = payload['old'];
12
},
13
).subscribe();

Broadcast#

Broadcast now uses the dedicated .onBroadcast() method, rather than the generic .on() method. Because the method is specific to broadcast, it takes fewer properties.

1
supabase.channel('my_channel').on(
2
RealtimeListenTypes.broadcast,
3
ChannelFilter(
4
event: 'position',
5
),
6
(dynamic payload, [ref]) {
7
print(payload);
8
},
9
).subscribe();

Presence#

Realtime Presence gets three different methods for listening to three different presence events: sync, join, and leave. This allows the callback to be strictly typed.

1
final channel = supabase.channel('room1');
2
3
channel.on(
4
RealtimeListenTypes.presence,
5
ChannelFilter(event: 'sync'),
6
(payload, [ref]) {
7
print('Synced presence state: ${channel.presenceState()}');
8
},
9
).on(
10
RealtimeListenTypes.presence,
11
ChannelFilter(event: 'join'),
12
(payload, [ref]) {
13
print('Newly joined presences $payload');
14
},
15
).on(
16
RealtimeListenTypes.presence,
17
ChannelFilter(event: 'leave'),
18
(payload, [ref]) {
19
print('Newly left presences: $payload');
20
},
21
).subscribe(
22
(status, [error]) async {
23
if (status == 'SUBSCRIBED') {
24
await channel.track({'online_at': DateTime.now().toIso8601String()});
25
}
26
},
27
);

delete

Perform a DELETE on the table or view.

  • delete() should always be combined with Filters to target the item(s) you wish to delete.
  • If you use delete() with filters and you have RLS enabled, only rows visible through SELECT policies are deleted. Note that by default no rows are visible, so you need at least one SELECT/ALL policy that makes the rows visible.
1
await supabase
2
.from('countries')
3
.delete()
4
.eq('id', 1);

insert

Perform an INSERT into the table or view.

Parameters

  • values
    Required
    Map<String, dynamic> or List<Map<String, dynamic>>

    The values to insert. Pass an object to insert a single row or an array to insert multiple rows.

1
await supabase
2
.from('cities')
3
.insert({'name': 'The Shire', 'country_id': 554});

rpc

Perform a function call.

You can call Postgres functions as Remote Procedure Calls, logic in your database that you can execute from anywhere. Functions are useful when the logic rarely changes—like for password resets and updates.

Parameters

  • fn
    Required
    String

    The function name to call.

  • params
    Optional
    Map<String, dynamic>

    The arguments to pass to the function call.

1
final data = await supabase
2
.rpc('hello_world');

select

Perform a SELECT query on the table or view.

  • By default, Supabase projects will return a maximum of 1,000 rows. This setting can be changed in Project API Settings. It's recommended that you keep it low to limit the payload size of accidental or malicious requests. You can use range() queries to paginate through your data.
  • select() can be combined with Filters
  • select() can be combined with Modifiers
  • apikey is a reserved keyword if you're using the Supabase Platform and should be avoided as a column name.

Parameters

  • columns
    Optional
    String

    The columns to retrieve, separated by commas. Columns can be renamed when returned with customName:columnName

1
final data = await supabase
2
.from('instruments')
3
.select();

update

Perform an UPDATE on the table or view.

  • update() should always be combined with Filters to target the item(s) you wish to update.

Parameters

  • values
    Required
    Map<String, dynamic>

    The values to update with.

1
await supabase
2
.from('instruments')
3
.update({ 'name': 'piano' })
4
.eq('id', 1);

upsert

Perform an UPSERT on the table or view. Depending on the column(s) passed to onConflict, .upsert() allows you to perform the equivalent of .insert() if a row with the corresponding onConflict columns doesn't exist, or if it does exist, perform an alternative action depending on ignoreDuplicates.

  • Primary keys must be included in values to use upsert.

Parameters

  • values
    Required
    Map<String, dynamic> or List<Map<String, dynamic>>

    The values to upsert with. Pass a Map to upsert a single row or an array to upsert multiple rows.

  • onConflict
    Optional
    String

    Comma-separated UNIQUE column(s) to specify how duplicate rows are determined. Two rows are duplicates if all the onConflict columns are equal.

  • ignoreDuplicates
    Optional
    bool

    If true, duplicate rows are ignored. If false, duplicate rows are merged with existing rows.

  • defaultToNull
    Optional
    bool

    Make missing fields default to null. Otherwise, use the default value for the column. This only applies when inserting new rows, not when merging with existing rows where ignoreDuplicates is set to false. This also only applies when doing bulk upserts.

1
final data = await supabase
2
.from('instruments')
3
.upsert({ 'id': 1, 'name': 'piano' })
4
.select();

Using filters

Filters allow you to only return rows that match certain conditions.

Filters can be used on select(), update(), upsert(), and delete() queries.

If a Database function returns a table response, you can also apply filters.

1
final data = await supabase
2
.from('cities')
3
.select('name, country_id')
4
.eq('name', 'The Shire'); // Correct
5
6
final data = await supabase
7
.from('cities')
8
.eq('name', 'The Shire') // Incorrect
9
.select('name, country_id');

containedBy

Only relevant for jsonb, array, and range columns. Match only rows where every element appearing in column is contained by value.

Parameters

  • column
    Required
    String

    The jsonb, array, or range column to filter on.

  • value
    Required
    Object

    The jsonb, array, or range value to filter with.

1
final data = await supabase
2
.from('classes')
3
.select('name')
4
.containedBy('days', ['monday', 'tuesday', 'wednesday', 'friday']);

contains

Only relevant for jsonb, array, and range columns. Match only rows where column contains every element appearing in value.

Parameters

  • column
    Required
    String

    The jsonb, array, or range column to filter on.

  • value
    Required
    Object

    The jsonb, array, or range value to filter with.

1
final data = await supabase
2
.from('issues')
3
.select()
4
.contains('tags', ['is:open', 'priority:low']);

eq

Match only rows where column is equal to value.

Parameters

  • column
    Required
    String

    The column to filter on.

  • value
    Required
    Object

    The value to filter with.

1
final data = await supabase
2
.from('instruments')
3
.select()
4
.eq('name', 'viola');

filter

Match only rows which satisfy the filter. This is an escape hatch - you should use the specific filter methods wherever possible.

.filter() expects you to use the raw PostgREST syntax for the filter names and values, so it should only be used as an escape hatch in case other filters don't work.

1
.filter('arraycol','cs','{"a","b"}') // Use Postgres array {} and 'cs' for contains.
2
.filter('rangecol','cs','(1,2]') // Use Postgres range syntax for range column.
3
.filter('id','in','(6,7)') // Use Postgres list () and 'in' for in_ filter.
4
.filter('id','cs','{${mylist.join(',')}}') // You can insert a Dart array list.

Parameters

  • column
    Required
    String

    The column to filter on.

  • operator
    Required
    String

    The operator to filter with, following PostgREST syntax.

  • value
    Required
    Object

    The value to filter with, following PostgREST syntax.

1
final data = await supabase
2
.from('characters')
3
.select()
4
.filter('name', 'in', '("Ron","Dumbledore")')

gt

Finds all rows whose value on the stated column is greater than the specified value.

Parameters

  • column
    Required
    String

    The column to filter on.

  • value
    Required
    Object

    The value to filter with.

1
final data = await supabase
2
.from('countries')
3
.select()
4
.gt('id', 2);

gte

Finds all rows whose value on the stated column is greater than or equal to the specified value.

Parameters

  • column
    Required
    String

    The column to filter on.

  • value
    Required
    Object

    The value to filter with.

1
final data = await supabase
2
.from('countries')
3
.select()
4
.gte('id', 2);

ilike

Finds all rows whose value in the stated column matches the supplied pattern (case insensitive).

Parameters

  • column
    Required
    String

    The column to filter on.

  • pattern
    Required
    String

    The pattern to match with.

1
final data = await supabase
2
.from('planets')
3
.select()
4
.ilike('name', '%ea%');

inFilter

Finds all rows whose value on the stated column is found on the specified values.

Parameters

  • column
    Required
    String

    The column to filter on.

  • values
    Required
    List

    The List to filter with.

1
final data = await supabase
2
.from('characters')
3
.select()
4
.inFilter('name', ['Luke', 'Leia']);

isFilter

A check for exact equality (null, true, false), finds all rows whose value on the stated column exactly match the specified value.

Parameters

  • column
    Required
    String

    The column to filter on.

  • value
    Required
    Object?

    The value to filter with.

1
final data = await supabase
2
.from('countries')
3
.select()
4
.isFilter('name', null);

like

Finds all rows whose value in the stated column matches the supplied pattern (case sensitive).

Parameters

  • column
    Required
    String

    The column to filter on.

  • pattern
    Required
    String

    The pattern to match with.

1
final data = await supabase
2
.from('planets')
3
.select()
4
.like('name', '%Ea%');

lt

Finds all rows whose value on the stated column is less than the specified value.

Parameters

  • column
    Required
    String

    The column to filter on.

  • value
    Required
    Object

    The value to filter with.

1
final data = await supabase
2
.from('countries')
3
.select()
4
.lt('id', 2);

lte

Finds all rows whose value on the stated column is less than or equal to the specified value.

Parameters

  • column
    Required
    String

    The column to filter on.

  • value
    Required
    Object

    The value to filter with.

1
final data = await supabase
2
.from('countries')
3
.select()
4
.lte('id', 2);

match

Finds all rows whose columns match the specified query object.

Parameters

  • query
    Required
    Map<String, dynamic>

    The object to filter with, with column names as keys mapped to their filter values

1
final data = await supabase
2
.from('instruments')
3
.select()
4
.match({ 'id': 2, 'name': 'viola' });

neq

Finds all rows whose value on the stated column doesn't match the specified value.

Parameters

  • column
    Required
    String

    The column to filter on.

  • value
    Required
    Object

    The value to filter with.

1
final data = await supabase
2
.from('instruments')
3
.select('id, name')
4
.neq('name', 'viola');

not

Finds all rows which doesn't satisfy the filter.

  • .not() expects you to use the raw PostgREST syntax for the filter names and values.

    1
    .not('name','eq','violin')
    2
    .not('arraycol','cs','{"a","b"}') // Use Postgres array {} for array column and 'cs' for contains.
    3
    .not('rangecol','cs','(1,2]') // Use Postgres range syntax for range column.
    4
    .not('id','in','(6,7)') // Use Postgres list () and 'in' instead of `inFilter`.
    5
    .not('id','in','(${mylist.join(',')})') // You can insert a Dart list array.

Parameters

  • column
    Required
    String

    The column to filter on.

  • operator
    Required
    String

    The operator to be negated to filter with, following PostgREST syntax.

  • value
    Optional
    Object

    The value to filter with, following PostgREST syntax.

1
final data = await supabase
2
.from('countries')
3
.select()
4
.not('name', 'is', null)

or

Finds all rows satisfying at least one of the filters.

  • .or() expects you to use the raw PostgREST syntax for the filter names and values.

    1
    .or('id.in.(6,7),arraycol.cs.{"a","b"}') // Use Postgres list () and 'in' instead of `inFilter`. Array {} and 'cs' for contains.
    2
    .or('id.in.(${mylist.join(',')}),arraycol.cs.{${mylistArray.join(',')}}') // You can insert a Dart list for list or array column.
    3
    .or('id.in.(${mylist.join(',')}),rangecol.cs.(${mylistRange.join(',')}]') // You can insert a Dart list for list or range column.

Parameters

  • filters
    Required
    String

    The filters to use, following PostgREST syntax

  • referencedTable
    Optional
    String

    Set this to filter on referenced tables instead of the parent table

1
final data = await supabase
2
.from('instruments')
3
.select('name')
4
.or('id.eq.2,name.eq.cello');

overlaps

Only relevant for array and range columns. Match only rows where column and value have an element in common.

Parameters

  • column
    Required
    String

    The array or range column to filter on.

  • value
    Required
    Object

    The array or range value to filter with.

1
final data = await supabase
2
.from('issues')
3
.select('title')
4
.overlaps('tags', ['is:closed', 'severity:high']);

rangeAdjacent

Only relevant for range columns. Match only rows where column is mutually exclusive to range and there can be no element between the two ranges.

Parameters

  • column
    Required
    String

    The range column to filter on.

  • range
    Required
    String

    The range to filter with.

1
final data = await supabase
2
.from('reservations')
3
.select()
4
.rangeAdjacent('during', '[2000-01-01 12:00, 2000-01-01 13:00)');

rangeGt

Only relevant for range columns. Match only rows where every element in column is greater than any element in range.

Parameters

  • column
    Required
    String

    The range column to filter on.

  • range
    Required
    String

    The range to filter with.

1
final data = await supabase
2
.from('reservations')
3
.select()
4
.rangeGt('during', '[2000-01-02 08:00, 2000-01-02 09:00)');

rangeGte

Only relevant for range columns. Match only rows where every element in column is either contained in range or greater than any element in range.

Parameters

  • column
    Required
    String

    The range column to filter on.

  • range
    Required
    String

    The range to filter with.

1
final data = await supabase
2
.from('reservations')
3
.select()
4
.rangeGte('during', '[2000-01-02 08:30, 2000-01-02 09:30)');

rangeLt

Only relevant for range columns. Match only rows where every element in column is less than any element in range.

Parameters

  • column
    Required
    String

    The range column to filter on.

  • range
    Required
    String

    The range to filter with.

1
final data = await supabase
2
.from('reservations')
3
.select()
4
.rangeLt('during', '[2000-01-01 15:00, 2000-01-01 16:00)');

rangeLte

Only relevant for range columns. Match only rows where every element in column is either contained in range or less than any element in range.

Parameters

  • column
    Required
    String

    The range column to filter on.

  • range
    Required
    String

    The range to filter with.

1
final data = await supabase
2
.from('reservations')
3
.select()
4
.rangeLte('during', '[2000-01-01 15:00, 2000-01-01 16:00)');

textSearch

Finds all rows whose tsvector value on the stated column matches to_tsquery(query).

Parameters

  • column
    Required
    String

    The text or tsvector column to filter on.

  • query
    Required
    String

    The query text to match with.

  • config
    Optional
    String

    The text search configuration to use.

  • type
    Optional
    TextSearchType

    Change how the query text is interpreted.


Using modifiers

Filters work on the row level. That is, they allow you to return rows that only match certain conditions without changing the shape of the rows. Modifiers are everything that don't fit that definition—allowing you to change the format of the response (e.g., returning a CSV string).

Modifiers must be specified after filters. Some modifiers only apply for queries that return rows (e.g., select() or rpc() on a function that returns a table response).


csv

1
final data = await supabase
2
.from('instruments')
3
.select()
4
.csv();

explain

For debugging slow queries, you can get the Postgres EXPLAIN execution plan of a query using the explain() method. This works on any query, even for rpc() or writes.

Explain is not enabled by default as it can reveal sensitive information about your database. It's best to only enable this for testing environments but if you wish to enable it for production you can provide additional protection by using a pre-request function.

Follow the Performance Debugging Guide to enable the functionality on your project.

Parameters

  • analyze
    Optional
    bool

    If true, the query will be executed and the actual run time will be returned.

  • verbose
    Optional
    bool

    If true, the query identifier will be returned and data will include the output columns of the query.

  • settings
    Optional
    bool

    If true, include information on configuration parameters that affect query planning.

  • buffers
    Optional
    bool

    If true, include information on buffer usage.

  • wal
    Optional
    bool

    If true, include information on WAL record generation.

  • format
    Optional
    ExplainFormat

    The output format of the execution plan. Either ExplainFormat.text (default) or ExplainFormat.json, in which case the plan is returned as a JSON string.

1
final data = await supabase
2
.from('instruments')
3
.select()
4
.explain();

limit

Limits the result with the specified count.

Parameters

  • count
    Required
    int

    The maximum number of rows to return.

  • referencedTable
    Optional
    int

    Set this to limit rows of referenced tables instead of the parent table.

1
final data = await supabase
2
.from('instruments')
3
.select('name')
4
.limit(1);

maxAffected

Sets the maximum number of rows that can be affected by the query. Only effective with PATCH and DELETE operations. Requires PostgREST v13 or higher.

When the limit is exceeded, the query will fail with an error. This provides a safety mechanism to prevent accidentally affecting more rows than intended.

  • This method is only effective with UPDATE and DELETE operations.
  • Requires PostgREST v13 or higher on your Supabase instance.
  • If the number of affected rows exceeds the limit, the query will fail and no rows will be modified.

Parameters

  • count
    Required
    int

    The maximum number of rows that can be affected by the query.

1
await supabase
2
.from('users')
3
.update({'active': false})
4
.eq('status', 'inactive')
5
.maxAffected(5);

maybeSingle

1
final data = await supabase
2
.from('instruments')
3
.select()
4
.eq('name', 'guzheng')
5
.maybeSingle();

order

Orders the result with the specified column.

Parameters

  • column
    Required
    String

    The column to order by.

  • ascending
    Optional
    bool

    Whether to order in ascending order. Default is false.

  • nullsFirst
    Optional
    bool

    Whether to order nulls first. Default is false.

  • referencedTable
    Optional
    String

    Specify the referenced table when ordering by a column in an embedded resource.

1
final data = await supabase
2
.from('instruments')
3
.select('id, name')
4
.order('id', ascending: false);

range

Limits the result to rows within the specified range, inclusive.

Parameters

  • from
    Required
    int

    The starting index from which to limit the result.

  • to
    Required
    int

    The last index to which to limit the result.

  • referencedTable
    Optional
    String

    Set this to limit rows of referenced tables instead of the parent table.

1
final data = await supabase
2
.from('instruments')
3
.select('name')
4
.range(0, 1);

select

1
final data = await supabase
2
.from('instruments')
3
.upsert({ 'id': 1, 'name': 'piano' })
4
.select();

single

Retrieves only one row from the result. Result must be one row (e.g. using limit), otherwise this will result in an error.

1
final data = await supabase
2
.from('instruments')
3
.select('name')
4
.limit(1)
5
.single();

stripNulls

Omits null-valued properties from the response objects.

  • This uses the nulls=stripped variant of the Accept header and requires PostgREST 11.2 or higher.
1
final data = await supabase
2
.from('users')
3
.select()
4
.stripNulls();

currentSession

Returns the session data, if there is an active session.

  • currentSession is a synchronous getter that returns whatever session is stored, even one whose access token has already expired.
  • getSession() is an asynchronous alternative that guarantees a valid access token when it resolves: a still-valid session is returned as-is, while an expired one is refreshed on demand first. It returns null when there is no session and throws an AuthException when an expired session cannot be refreshed.
1
final Session? session = supabase.auth.currentSession;

currentUser

Returns the user data, if there is a logged in user.


getUserIdentities

Gets all the identities linked to a user.

  • The user needs to be signed in to call getUserIdentities().
1
final identities = await supabase.auth.getUserIdentities();

linkIdentity

Links an oauth identity to an existing user. This method supports the PKCE flow.

  • The Enable Manual Linking option must be enabled from your project's authentication settings.
  • The user needs to be signed in to call linkIdentity().
  • If the candidate identity is already linked to the existing user or another user, linkIdentity() will fail.

Parameters

  • provider
    Required
    OAuthProvider

    The provider to link the identity to.

  • redirectTo
    Optional
    String

    The URL to redirect the user to after they sign in with the third-party provider.

  • scopes
    Optional
    String

    A list of scopes to request from the third-party provider.

  • authScreenLaunchMode
    Optional
    LaunchMode

    The launch mode for the auth screen. Defaults to LaunchMode.platformDefault.

  • queryParams
    Optional
    Map<String, String>

    Additional query parameters to be passed to the OAuth flow.


linkIdentityWithIdToken

Links an identity to an existing user using an ID token obtained from a third-party OAuth provider. This allows linking identities using native OAuth flows (Google, Apple, Facebook, etc.) similar to signInWithIdToken() but for linking rather than signing in.

  • The Enable Manual Linking option must be enabled from your project's authentication settings.
  • The user needs to be signed in to call linkIdentityWithIdToken().
  • Supports the same OAuth providers as signInWithIdToken(): Google, Apple, Facebook, Kakao, and Keycloak.
  • If the candidate identity is already linked to another user, the operation will fail.

Parameters

  • provider
    Required
    OAuthProvider

    The OAuth provider to link the identity from.

  • idToken
    Required
    String

    The identity token obtained from the third-party provider.

  • accessToken
    Optional
    String

    Access token obtained from the third-party provider. Required for Google sign in.

  • nonce
    Optional
    String

    Raw nonce value used to perform the third-party sign in. Required for Apple sign-in.

  • captchaToken
    Optional
    String

    The captcha token to be used for captcha verification.


onAuthStateChange

Receive a notification every time an auth event happens.

  • You must provide an onError handler. Network errors (e.g. an offline token refresh) are emitted as stream errors. If no onError is provided, Dart rethrows them as unhandled zone exceptions, crashing the app.
  • Auth event types: initialSession, signedIn, signedOut, passwordRecovery, tokenRefreshed, userUpdated, userDeleted, mfaChallengeVerified
1
final authSubscription = supabase.auth.onAuthStateChange.listen(
2
(data) {
3
final AuthChangeEvent event = data.event;
4
final Session? session = data.session;
5
// handle event
6
},
7
onError: (error, stackTrace) {
8
// Network errors (e.g. offline) are emitted here.
9
// Handle or log them to avoid an unhandled exception crash.
10
},
11
);

reauthenticate

  • This method is used together with updateUser() when a user's password needs to be updated.
  • This method sends a nonce to the user's email. If the user doesn't have a confirmed email address, the method sends the nonce to the user's confirmed phone number instead.
1
await supabase.auth.reauthenticate();

refreshSession

  • This method will refresh and return a new session whether the current one is expired or not.
1
final AuthResponse res = await supabase.auth.refreshSession();
2
final session = res.session;

registerPasskey

Registers a new passkey (WebAuthn credential) for the signed in user.

  • Available on supabase_flutter 2.15.0 and later as an extension on GoTrueClient.
  • Drives the full WebAuthn ceremony end to end: starts the registration with the Supabase server, calls the authenticator you supply to create a credential on the device, and verifies it with the server.
  • Requires a signed in (non-anonymous) user. If the user has verified MFA factors, the session has to be at aal2 to manage passkeys.
  • supabase_flutter does not depend on a passkey plugin directly. Pass an implementation of PasskeyAuthenticatorInterface, such as the passkeys plugin's PasskeyAuthenticator (since passkeys 2.21.0).
  • For native flows or custom UI, use the lower-level auth.passkey namespace instead.
  • Passkeys are a BETA feature and must be enabled for your project in the Supabase Dashboard under Authentication > Configuration > Passkeys.

Parameters

  • authenticator
    Required
    PasskeyAuthenticatorInterface

    Performs the platform passkey ceremony (FaceID/TouchID/security key). For example, a PasskeyAuthenticator from the passkeys package.

  • friendlyName
    Optional
    String

    Human readable name for the passkey. Used as a fallback for the WebAuthn user.name/displayName when the server omits them, and stored as the passkey's friendly name. Defaults to Passkey when not provided.

1
import 'package:passkeys/authenticator.dart';
2
3
final authenticator = PasskeyAuthenticator();
4
5
final Passkey passkey = await supabase.auth.registerPasskey(
6
authenticator,
7
friendlyName: 'Work laptop',
8
);

resend

  • Resends a signup confirmation, email change, or phone change email to the user.
  • Passwordless sign-ins can be resent by calling the signInWithOtp() method again.
  • Password recovery emails can be resent by calling the resetPasswordForEmail() method again.
  • This method only resend an email or phone OTP to the user if an initial signup, email change, or phone change request was made.
1
final ResendResponse res = await supabase.auth.resend(
2
type: OtpType.signup,
3
email: 'email@example.com',
4
);

resetPasswordForEmail

Sends a reset request to an email address.

Sends a password reset request to an email address. When the user clicks the reset link in the email they are redirected back to your application. Prompt the user for a new password and call auth.updateUser():

1
await supabase.auth.resetPasswordForEmail(
2
'sample@email.com',
3
redirectTo: kIsWeb ? null : 'io.supabase.flutter://reset-callback/',
4
);

redirectTo is used to open the app via deeplink when user opens the password reset email.

1
await supabase.auth.resetPasswordForEmail(
2
'sample@email.com',
3
redirectTo: kIsWeb ? null : 'io.supabase.flutter://reset-callback/',
4
);

setSession

  • setSession() takes in a refresh token and uses it to get a new session.
  • The refresh token can only be used once to obtain a new session.
  • Refresh token rotation is enabled by default on all projects to guard against replay attacks.
  • You can configure the REFRESH_TOKEN_REUSE_INTERVAL which provides a short window in which the same refresh token can be used multiple times in the event of concurrency or offline issues.

Parameters

  • refreshToken
    Required
    String

    Refresh token to use to get a new session.

  • accessToken
    Optional
    String

    Optional access token to set along with the refresh token.

1
final refreshToken = supabase.currentSession?.refreshToken ?? '';
2
final AuthResponse response = await supabase.auth.setSession(refreshToken);
3
4
final session = res.session;

signInAnonymously

Creates an anonymous user.

  • Returns an anonymous user
  • It is recommended to set up captcha for anonymous sign-ins to prevent abuse. You can pass in the captcha token in the options param.

Parameters

  • data
    Optional
    Map<String, dynamic>

    The user's metadata to be stored in the user's object.

  • captchaToken
    Optional
    String

    The captcha token to be used for captcha verification.

1
await supabase.auth.signInAnonymously();

signInWithIdToken

Allows you to perform native Google, Apple, and Facebook sign in by combining it with google_sign_in, sign_in_with_apple, or flutter_facebook_auth packages.

Parameters

  • provider
    Required
    OAuthProvider

    The provider to perform the sign in with.

  • idToken
    Required
    String

    The identity token obtained from the third-party provider.

  • accessToken
    Optional
    String

    Access token obtained from the third-party provider. Required for Google sign in.

  • nonce
    Optional
    String

    Raw nonce value used to perform the third-party sign in. Required for Apple sign-in.

  • captchaToken
    Optional
    String

    The captcha token to be used for captcha verification.

1
import 'package:google_sign_in/google_sign_in.dart';
2
import 'package:supabase_flutter/supabase_flutter.dart';
3
4
const webClientId = '<web client ID that you registered on Google Cloud, for example my-web.apps.googleusercontent.com>';
5
6
const iosClientId = '<iOS client ID that you registered on Google Cloud, for example my-ios.apps.googleusercontent.com';
7
8
final GoogleSignIn googleSignIn = GoogleSignIn(
9
clientId: iosClientId,
10
serverClientId: webClientId,
11
);
12
final googleUser = await googleSignIn.signIn();
13
final googleAuth = await googleUser!.authentication;
14
final accessToken = googleAuth.accessToken;
15
final idToken = googleAuth.idToken;
16
17
if (accessToken == null) {
18
throw 'No Access Token found.';
19
}
20
if (idToken == null) {
21
throw 'No ID Token found.';
22
}
23
24
final response = await supabase.auth.signInWithIdToken(
25
provider: OAuthProvider.google,
26
idToken: idToken,
27
accessToken: accessToken,
28
);

signInWithOAuth

Signs the user in using third-party OAuth providers.

  • This method is used for signing in using a third-party provider.
  • Supabase supports many different third-party providers.

Parameters

  • provider
    Required
    OAuthProvider

    The OAuth provider to use for signing in.

  • redirectTo
    Optional
    String

    The URL to redirect the user to after they sign in with the third-party provider.

  • scopes
    Optional
    String

    A list of scopes to request from the third-party provider.

  • authScreenLaunchMode
    Optional
    LaunchMode

    The launch mode for the auth screen. Defaults to LaunchMode.platformDefault.

  • queryParams
    Optional
    Map<String, String>

    Additional query parameters to be passed to the OAuth flow.

1
await supabase.auth.signInWithOAuth(
2
OAuthProvider.github,
3
redirectTo: kIsWeb ? null : 'my.scheme://my-host', // Optionally set the redirect link to bring back the user via deeplink.
4
authScreenLaunchMode:
5
kIsWeb ? LaunchMode.platformDefault : LaunchMode.externalApplication, // Launch the auth screen in a new webview on mobile.
6
);

signInWithOtp

  • Requires either an email or phone number.
  • This method is used for passwordless sign-ins where an OTP is sent to the user's email or phone number.
  • If you're using an email, you can configure whether you want the user to receive a magiclink or an OTP.
  • If you're using phone, you can configure whether you want the user to receive an OTP.
  • The magic link's destination URL is determined by the SITE_URL. You can modify the SITE_URL or add additional redirect urls in your project.

Parameters

  • email
    Optional
    String

    Email address to send the magic link or OTP to.

  • phone
    Optional
    String

    Phone number to send the OTP to.

  • emailRedirectTo
    Optional
    String

    The URL to redirect the user to after they click on the magic link.

  • shouldCreateUser
    Optional
    bool

    If set to false, this method will not create a new user. Defaults to true.

  • data
    Optional
    Map<String, dynamic>

    The user's metadata to be stored in the user's object.

  • captchaToken
    Optional
    String

    The captcha token to be used for captcha verification.

  • channel
    Optional
    OtpChannel

    Messaging channel to use (e.g. whatsapp or sms). Defaults to OtpChannel.sms.

1
await supabase.auth.signInWithOtp(
2
email: 'example@email.com',
3
emailRedirectTo: kIsWeb ? null : 'io.supabase.flutter://signin-callback/',
4
);

signInWithPasskey

Signs the user in with a passkey (WebAuthn).

  • Available on supabase_flutter 2.15.0 and later as an extension on GoTrueClient.
  • Drives the full WebAuthn ceremony end to end: starts the challenge with the Supabase server, calls the authenticator you supply to prompt the user for biometrics or a security key, and verifies the credential with the server.
  • Does not require an existing session. On success the session is persisted and an AuthChangeEvent.signedIn event is fired.
  • supabase_flutter does not depend on a passkey plugin directly. Pass an implementation of PasskeyAuthenticatorInterface, such as the passkeys plugin's PasskeyAuthenticator (since passkeys 2.21.0).
  • For native flows or custom UI, use the lower-level auth.passkey namespace instead.
  • Passkeys are a BETA feature and must be enabled for your project in the Supabase Dashboard under Authentication > Configuration > Passkeys.
  • Platform setup the library cannot perform (Associated Domains on iOS/macOS, Digital Asset Links on Android, the passkeys web SDK on web) is documented in the supabase_flutter package README.

Parameters

  • authenticator
    Required
    PasskeyAuthenticatorInterface

    Performs the platform passkey ceremony (FaceID/TouchID/security key). For example, a PasskeyAuthenticator from the passkeys package.

  • captchaToken
    Optional
    String

    Captcha token to be used for captcha verification.

1
import 'package:passkeys/authenticator.dart';
2
3
final authenticator = PasskeyAuthenticator();
4
5
final AuthResponse res = await supabase.auth.signInWithPasskey(authenticator);
6
final Session? session = res.session;
7
final User? user = res.user;

signInWithPassword

Log in an existing user using email or phone number with password.

  • Requires either an email and password or a phone number and password.

Parameters

  • email
    Optional
    String

    User's email address to be used for email authentication.

  • phone
    Optional
    String

    User's phone number to be used for phone authentication.

  • password
    Required
    String

    Password to be used for authentication.

  • captchaToken
    Optional
    String

    The captcha token to be used for captcha verification.

1
final AuthResponse res = await supabase.auth.signInWithPassword(
2
email: 'example@email.com',
3
password: 'example-password',
4
);
5
final Session? session = res.session;
6
final User? user = res.user;

signInWithSSO

  • Before you can call this method you need to establish a connection to an identity provider. Use the CLI commands to do this.
  • If you've associated an email domain to the identity provider, you can use the domain property to start a sign-in flow.
  • In case you need to use a different way to start the authentication flow with an identity provider, you can use the providerId property. For example:
    • Mapping specific user email addresses with an identity provider.
    • Using different hints to identify the correct identity provider, like a company-specific page, IP address or other tracking information.

Parameters

  • providerId
    Optional
    String

    The ID of the SSO provider to use for signing in.

  • domain
    Optional
    String

    The email domain to use for signing in.

  • redirectTo
    Optional
    String

    The URL to redirect the user to after they sign in with the third-party provider.

  • captchaToken
    Optional
    String

    The captcha token to be used for captcha verification.

  • launchMode
    Optional
    LaunchMode

    The launch mode for the auth screen. Defaults to LaunchMode.platformDefault.

1
await supabase.auth.signInWithSSO(
2
domain: 'company.com',
3
);

signInWithWeb3

Signs in a user by verifying a message signed with their Web3 wallet.

  • Supports Ethereum (Sign-In with Ethereum) and Solana (Sign-In with Solana), both of which derive from the EIP-4361 standard.
  • Handle the wallet interaction and message signing yourself with the wallet library of your choice, then provide the signed message together with its signature.
  • For Web3Chain.ethereum the signature is a hex encoded string. For Web3Chain.solana it is a base64url encoded string.
  • On success, it signs the user in and returns a session. On failure, it throws an AuthException.

Parameters

  • chain
    Required
    Web3Chain

    The blockchain used to sign in. One of Web3Chain.ethereum or Web3Chain.solana.

  • message
    Required
    String

    The EIP-4361 message that was signed by the user's wallet.

  • signature
    Required
    String

    The signature produced by the wallet. Hex encoded for Ethereum, base64url encoded for Solana.

  • captchaToken
    Optional
    String

    The verification token received when the user completes the captcha on the app.

1
final response = await supabase.auth.signInWithWeb3(
2
chain: Web3Chain.ethereum,
3
message: message, // The EIP-4361 message signed by the wallet.
4
signature: signature, // Hex encoded signature.
5
);
6
final session = response.session;

signOut

Signs out the current user, if there is a logged in user.

  • In order to use the signOut() method, the user needs to be signed in first.

Parameters

  • scope
    Optional
    SignOutScope

    Whether to sign out from all devices or just the current device. Defaults to SignOutScope.local.

1
await supabase.auth.signOut();

signUp

Creates a new user.

  • By default, the user needs to verify their email address before logging in. To turn this off, disable Confirm email in your project.
  • Confirm email determines if users need to confirm their email address after signing up.
    • If Confirm email is enabled, a user is returned but session is null.
    • If Confirm email is disabled, both a user and a session are returned.
  • When the user confirms their email address, they are redirected to the SITE_URL by default. You can modify your SITE_URL or add additional redirect URLs in your project.
  • If signUp() is called for an existing confirmed user:
    • When both Confirm email and Confirm phone (even when phone provider is disabled) are enabled in your project, an obfuscated/fake user object is returned.
    • When either Confirm email or Confirm phone (even when phone provider is disabled) is disabled, the error message, User already registered is returned.

Parameters

  • email
    Optional
    String

    User's email address to be used for email authentication.

  • phone
    Optional
    String

    User's phone number to be used for phone authentication.

  • password
    Required
    String

    Password to be used for authentication.

  • emailRedirectTo
    Optional
    String

    The URL to redirect the user to after they confirm their email address.

  • data
    Optional
    Map<String, dynamic>

    The user's metadata to be stored in the user's object.

  • captchaToken
    Optional
    String

    The captcha token to be used for captcha verification.

  • channel
    Optional
    OtpChannel

    Messaging channel to use (e.g. whatsapp or sms). Defaults to OtpChannel.sms.

1
final AuthResponse res = await supabase.auth.signUp(
2
email: 'example@email.com',
3
password: 'example-password',
4
);
5
final Session? session = res.session;
6
final User? user = res.user;

unlinkIdentity

Unlinks an identity from a user by deleting it. The user will no longer be able to sign in with that identity once it's unlinked.

  • The Enable Manual Linking option must be enabled from your project's authentication settings.
  • The user needs to be signed in to call unlinkIdentity().
  • The user must have at least 2 identities in order to unlink an identity.
  • The identity to be unlinked must belong to the user.

Parameters

  • identity
    Required
    UserIdentity

    The user identity to unlink.


updateUser

Updates user data for a logged in user.

  • In order to use the updateUser() method, the user needs to be signed in first.
  • By default, email updates sends a confirmation link to both the user's current and new email. To only send a confirmation link to the user's new email, disable Secure email change in your project's email auth provider settings.

Parameters

  • attributes
    Required
    UserAttributes

    Attributes to update for the user.

  • emailRedirectTo
    Optional
    String

    The URI to redirect the user to after the email is updated.

1
final UserResponse res = await supabase.auth.updateUser(
2
UserAttributes(
3
email: 'example@email.com',
4
),
5
);
6
final User? updatedUser = res.user;

verifyOtp

  • The verifyOtp method takes in different verification types. If a phone number is used, the type can either be sms or phone_change. If an email address is used, the type can be one of the following: email, recovery, invite or email_change (signup and magiclink types are deprecated).
  • The verification type used should be determined based on the corresponding auth method called before verifyOtp to sign up or sign in a user.

Parameters

  • token
    Required
    String

    The token that user was sent to their email or mobile phone

  • type
    Required
    OtpType

    Type of the OTP to verify

  • email
    Optional
    String

    Email address that the OTP was sent to

  • phone
    Optional
    String

    Phone number that the OTP was sent to

  • redirectTo
    Optional
    String

    URI to redirect the user to after the OTP is verified

  • captchaToken
    Optional
    String

    The captcha token to be used for captcha verification

  • tokenHash
    Optional
    String

    Token used in an email link

1
final AuthResponse res = await supabase.auth.verifyOTP(
2
type: OtpType.signup,
3
token: token,
4
phone: '+13334445555',
5
);
6
final Session? session = res.session;
7
final User? user = res.user;

Auth Admin

  • Any method under the supabase.auth.admin namespace requires a secret key.
  • These methods are considered admin methods and should be called on a trusted server. Never expose your secret key in the Flutter app.
1
final supabase = SupabaseClient(supabaseUrl, secretKey);

createUser

Creates a new user.

  • To confirm the user's email address or phone number, set email_confirm or phone_confirm to true. Both arguments default to false.
  • createUser() will not send a confirmation email to the user. You can use inviteUserByEmail() if you want to send them an email invite instead.
  • If you are sure that the created user's email or phone number is legitimate and verified, you can set the email_confirm or phone_confirm param to true.

Parameters

  • attributes
    Required
    AdminUserAttributes

    Attributes to create the user with.

1
final res = await supabase.auth.admin.createUser(AdminUserAttributes(
2
email: 'user@email.com',
3
password: 'password',
4
userMetadata: {'name': 'Yoda'},
5
));

deleteUser

Delete a user.

  • The deleteUser() method requires the user's ID, which maps to the auth.users.id column.
  • When shouldSoftDelete is true, the user is soft-deleted: their record and associated data are retained but the user is marked as deleted. Defaults to false, which permanently removes the user.

Parameters

  • id
    Required
    String

    ID of the user to be deleted.

  • shouldSoftDelete
    Optional
    bool

    If true, soft-deletes the user (keeps the record but marks it deleted). Defaults to false (permanent delete).

1
await supabase.auth.admin
2
.deleteUser('715ed5db-f090-4b8c-a067-640ecee36aa0');


getUserById

Get user by id.

  • Fetches the user object from the database based on the user's id.
  • The getUserById() method requires the user's id which maps to the auth.users.id column.

Parameters

  • uid
    Required
    String

    User ID of the user to fetch.

1
final res = await supabase.auth.admin.getUserById(userId);
2
final user = res.user;

inviteUserByEmail

Sends an invite link to the user's email address.

Parameters

  • email
    Required
    String

    Email address of the user to invite.

  • redirectTo
    Optional
    String

    URI to redirect the user to after they open the invite link.

  • data
    Optional
    Map<String, dynamic>

    A custom data object to store the user's metadata. This maps to the auth.users.user_metadata column.

1
final UserResponse res = await supabase.auth.admin
2
.inviteUserByEmail('email@example.com');
3
final User? user = res.user;

listUsers

Get a list of users.

  • Defaults to return 50 users per page.

Parameters

  • page
    Optional
    int

    What page of users to return.

  • page
    Optional
    int

    How many users to be returned per page. Defaults to 50.

1
// Returns the first 50 users.
2
final List<User> users = await supabase.auth.admin.listUsers();

updateUserById

Parameters

  • uid
    Required
    GenerateLinkType

    User ID of the user to update.

  • attributes
    Required
    AdminUserAttributes

    Attributes to update for the user.

1
await supabase.auth.admin.updateUserById(
2
'6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4',
3
attributes: AdminUserAttributes(
4
email: 'new@email.com',
5
),
6
);

Auth MFA

This section contains methods commonly used for Multi-Factor Authentication (MFA) and are invoked behind the supabase.auth.mfa namespace.

Currently, Supabase supports time-based one-time password (TOTP) and phone verification code as the 2nd factor. Recovery codes are not supported but users can enroll multiple factors, with an upper limit of 10..

Having a 2nd factor for recovery frees the user of the burden of having to store their recovery codes somewhere. It also reduces the attack surface since multiple recovery codes are usually generated compared to just having 1 backup factor.

Learn more about implementing MFA on your application on our guide here.


challenge

Prepares a challenge used to verify that a user has access to a MFA factor.

Parameters

  • factorId
    Required
    String

    System assigned identifier for authenticator device as returned by enroll

  • channel
    Optional
    OtpChannel

    Messaging channel to use for phone factors (e.g. OtpChannel.whatsapp or OtpChannel.sms). Defaults to the server's behavior (SMS) when omitted. Ignored for TOTP factors.

1
final res = await supabase.auth.mfa.challenge(
2
factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225',
3
);

challengeAndVerify

Helper method which creates a challenge and immediately uses the given code to verify against it thereafter. The verification code is provided by the user by entering a code seen in their authenticator app.

Parameters

  • factorId
    Required
    String

    System assigned identifier for authenticator device as returned by enroll

  • code
    Required
    String

    The verification code on the user's authenticator app

1
final res = await supabase.auth.mfa.challengeAndVerify(
2
factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225',
3
code: '123456',
4
);

enroll

Starts the enrollment process for a new Multi-Factor Authentication (MFA) factor. This method creates a new unverified factor. To verify a factor, present the QR code or secret to the user and ask them to add it to their authenticator app. The user has to enter the code from their authenticator app to verify it.

Parameters

  • factorType
    Optional
    String

    Type of factor being enrolled.

  • issuer
    Optional
    String

    Domain which the user is enrolled with.

  • friendlyName
    Optional
    String

    Human readable name assigned to the factor.

  • phone
    Optional
    String

    Phone number to enroll for phone factor type.

1
final res = await supabase.auth.mfa.enroll(factorType: FactorType.totp);
2
3
final qrCodeUrl = res.totp.qrCode;

getAuthenticatorAssuranceLevel

Returns the Authenticator Assurance Level (AAL) for the active session.

  • Authenticator Assurance Level (AAL) is the measure of the strength of an authentication mechanism.
  • In Supabase, having an AAL of aal1 means the user has signed in with their first factor, such as email, password, or OAuth sign-in. An AAL of aal2 means the user has also signed in with their second factor, such as a time-based, one-time-password (TOTP).
  • If the user has a verified factor, the nextLevel field returns aal2. Otherwise, it returns aal1.
1
final res = supabase.auth.mfa.getAuthenticatorAssuranceLevel();
2
final currentLevel = res.currentLevel;
3
final nextLevel = res.nextLevel;
4
final currentAuthenticationMethods = res.currentAuthenticationMethods;

unenroll

Unenroll removes a MFA factor. A user has to have an aal2 authenticator level in order to unenroll a verified factor.

Parameters

  • factorId
    Required
    String

    System assigned identifier for authenticator device as returned by enroll

1
final res = await supabase.auth.mfa.unenroll(
2
'34e770dd-9ff9-416c-87fa-43b31d7ef225',
3
);

verify

Verifies a code against a challenge. The verification code is provided by the user by entering a code seen in their authenticator app.

Parameters

  • factorId
    Required
    String

    System assigned identifier for authenticator device as returned by enroll

  • challengeId
    Required
    String

    The ID of the challenge to verify

  • code
    Required
    String

    The verification code on the user's authenticator app

1
final res = await supabase.auth.mfa.verify(
2
factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225',
3
challengeId: '4034ae6f-a8ce-4fb5-8ee5-69a5863a7c15',
4
code: '123456',
5
);

Auth Passkey

This section contains methods for WebAuthn passkey registration, authentication, and management. Methods are invoked behind the supabase.auth.passkey namespace.

These methods expose the server side of the WebAuthn ceremony. The client side (the FaceID/TouchID/security key prompt) has to be performed with a platform passkey API: navigator.credentials.create()/get() on web, or a passkey plugin on iOS/Android/macOS. Options and credentials are exchanged as Map<String, dynamic> in the W3C WebAuthn Level 3 JSON format.

For a one-call alternative that runs the full ceremony, see signInWithPasskey() and registerPasskey() on supabase_flutter.

Passkey support is a BETA feature and must be enabled for your project in the Supabase Dashboard under Authentication > Configuration > Passkeys.


delete

Deletes a passkey from the signed in user.

  • If the user has verified MFA factors, the session has to be at aal2 to manage passkeys.

Parameters

  • passkeyId
    Required
    String

    ID of the passkey to delete.

1
await supabase.auth.passkey.delete(
2
passkeyId: '34e770dd-9ff9-416c-87fa-43b31d7ef225',
3
);

list

Returns the list of passkeys registered to the signed in user.

1
final List<Passkey> passkeys = await supabase.auth.passkey.list();

startAuthentication

Starts a passkey sign in.

  • Does not require an existing session.
  • Pass the returned options to the platform's passkey API to obtain an assertion, then call passkey.verifyAuthentication() with the result.

Parameters

  • captchaToken
    Optional
    String

    Captcha token to be used for captcha verification.

1
final PasskeyAuthenticationOptionsResponse authentication =
2
await supabase.auth.passkey.startAuthentication();
3
4
// Hand authentication.options to the platform passkey API.

startRegistration

Starts the registration of a new passkey for the signed in user.

  • Requires a signed in (non-anonymous) user.
  • Pass the returned options to the platform's passkey API to create the credential, then call passkey.verifyRegistration() with the result.
  • When the server omits user.name/displayName in the registration options, they are backfilled with friendlyName (or a generic Passkey default) before the platform ceremony.

Parameters

  • friendlyName
    Optional
    String

    Human readable name used as a fallback for the WebAuthn user.name/displayName when the server omits them. Defaults to Passkey when not provided.

1
final PasskeyRegistrationOptionsResponse registration =
2
await supabase.auth.passkey.startRegistration(
3
friendlyName: 'Work laptop',
4
);
5
6
// Hand registration.options to the platform passkey API.

update

Updates the friendly name of a passkey.

Parameters

  • passkeyId
    Required
    String

    ID of the passkey to rename.

  • friendlyName
    Required
    String

    New human readable name for the passkey. Limited to 120 characters.

1
final Passkey passkey = await supabase.auth.passkey.update(
2
passkeyId: '34e770dd-9ff9-416c-87fa-43b31d7ef225',
3
friendlyName: 'Work laptop',
4
);

verifyAuthentication

Completes a passkey sign in and returns the new session.

  • On success the session is persisted and an AuthChangeEvent.signedIn event is fired.

Parameters

  • challengeId
    Required
    String

    The challenge ID returned by passkey.startAuthentication().

  • credential
    Required
    Map<String, dynamic>

    The assertion produced by the platform's passkey API, serialized in the W3C AuthenticationResponseJSON format.

1
final AuthResponse res = await supabase.auth.passkey.verifyAuthentication(
2
challengeId: authentication.challengeId,
3
credential: credential,
4
);
5
final Session? session = res.session;
6
final User? user = res.user;

verifyRegistration

Completes the registration of a new passkey and returns the stored Passkey.

Parameters

  • challengeId
    Required
    String

    The challenge ID returned by passkey.startRegistration().

  • credential
    Required
    Map<String, dynamic>

    The credential created by the platform's passkey API, serialized in the W3C RegistrationResponseJSON format.

1
final Passkey passkey = await supabase.auth.passkey.verifyRegistration(
2
challengeId: registration.challengeId,
3
credential: credential,
4
);

Custom Provider Admin

  • Methods under the supabase.auth.admin.customProviders namespace manage custom OIDC/OAuth providers programmatically. Requires a secret key.
  • These are admin methods and should be called on a trusted server. Never expose your secret key in the Flutter app.
  • Custom providers are referenced with a custom: prefix when signing in (for example custom:mycompany), and are distinct from the OAuth 2.1 server clients managed through supabase.auth.admin.oauth.

createProvider

Creates a new custom OIDC/OAuth provider. For OIDC providers, the server fetches and validates the discovery document at creation time and throws an AuthException with code validation_failed if it is unreachable or invalid.

Parameters

  • params
    Required
    CreateCustomProviderParams

    The provider configuration, including providerType, identifier, name, clientId, clientSecret, and optional fields such as customClaimsAllowlist.

1
final CustomOAuthProvider provider =
2
await supabase.auth.admin.customProviders.createProvider(
3
CreateCustomProviderParams(
4
providerType: CustomProviderType.oidc,
5
identifier: 'custom:mycompany',
6
name: 'My Company',
7
clientId: 'client-id',
8
clientSecret: 'client-secret',
9
issuer: 'https://auth.mycompany.com',
10
customClaimsAllowlist: ['groups', 'org_id'],
11
),
12
);

deleteProvider

Deletes a custom provider by its identifier.

Parameters

  • identifier
    Required
    String

    The provider identifier, for example custom:mycompany.

1
await supabase.auth.admin.customProviders.deleteProvider('custom:mycompany');

getProvider

Gets details of a specific custom provider by its identifier.

Parameters

  • identifier
    Required
    String

    The provider identifier, for example custom:mycompany.

1
final CustomOAuthProvider provider =
2
await supabase.auth.admin.customProviders.getProvider('custom:mycompany');

listProviders

Lists all custom providers, optionally filtered by provider type.

Parameters

  • type
    Optional
    CustomProviderType

    When set, only providers of this type are returned. Either CustomProviderType.oauth2 or CustomProviderType.oidc.

1
final List<CustomOAuthProvider> providers =
2
await supabase.auth.admin.customProviders.listProviders();

updateProvider

Updates an existing custom provider. When issuer or discoveryUrl changes on an OIDC provider, the server re-fetches and validates the discovery document before persisting.

Parameters

  • identifier
    Required
    String

    The provider identifier, for example custom:mycompany.

  • params
    Required
    UpdateCustomProviderParams

    The fields to update on the provider.

1
final CustomOAuthProvider provider =
2
await supabase.auth.admin.customProviders.updateProvider(
3
'custom:mycompany',
4
UpdateCustomProviderParams(
5
customClaimsAllowlist: ['groups', 'org_id', 'mail'],
6
),
7
);

OAuth Server

Methods under the supabase.auth.oauth namespace are used when your Supabase project acts as an OAuth 2.1 server. They drive the user-facing consent flow, let users manage the grants they have issued to third-party clients, and require a signed-in user. The OAuth 2.1 server feature must be enabled in your Supabase Auth configuration.


approveAuthorization

Approves a pending OAuth authorization request on behalf of the signed-in user. The response contains the redirect URL the user should be sent to.

Parameters

  • authorizationId
    Required
    String

    The unique identifier of the pending authorization request.

1
final consent =
2
await supabase.auth.oauth.approveAuthorization(authorizationId);
3
// Redirect the user to consent.redirectUrl

denyAuthorization

Denies a pending OAuth authorization request on behalf of the signed-in user. The response contains the redirect URL the user should be sent to.

Parameters

  • authorizationId
    Required
    String

    The unique identifier of the pending authorization request.

1
final consent =
2
await supabase.auth.oauth.denyAuthorization(authorizationId);
3
// Redirect the user to consent.redirectUrl

getAuthorizationDetails

Retrieves details about a pending OAuth authorization request so you can render a consent screen. The authorizationId is provided as a query parameter on the redirect URL that starts the flow.

  • Returns a sealed OAuthAuthorizationResponse. Handle both variants: OAuthAuthorizationDetailsResponse carries the requesting client and requested scope for the consent screen, while OAuthAuthorizationRedirectResponse is returned when the user has already granted consent and only carries a redirectUrl to forward to.

Parameters

  • authorizationId
    Required
    String

    The unique identifier of the pending authorization request.

1
final authorizationId =
2
Uri.parse(currentUrl).queryParameters['authorization_id']!;
3
4
final response =
5
await supabase.auth.oauth.getAuthorizationDetails(authorizationId);
6
7
switch (response) {
8
case OAuthAuthorizationRedirectResponse(:final redirectUrl):
9
// The user already consented; forward them without a consent screen.
10
break;
11
case OAuthAuthorizationDetailsResponse(:final client, :final scope):
12
// Render a consent screen for `client` requesting `scope`.
13
break;
14
}

listGrants

Lists the OAuth grants the signed-in user has issued to third-party OAuth clients.

  • Requires an authenticated user. Returns the grants issued by the current user.
1
final List<OAuthGrant> grants = await supabase.auth.oauth.listGrants();
2
3
for (final grant in grants) {
4
print('${grant.client.clientId}: ${grant.scopes}');
5
}

revokeGrant

Revokes a grant the signed-in user previously issued to a third-party OAuth client.

Parameters

  • clientId
    Required
    String

    The identifier of the OAuth client whose grant should be revoked.

1
await supabase.auth.oauth.revokeGrant('client-id');

Passkey Admin

Contains passkey administration methods, accessed under the supabase.auth.admin.passkey namespace. Requires a secret key.

Passkey support is a BETA feature and must be enabled for your project in the Supabase Dashboard under Authentication > Configuration > Passkeys.


deletePasskey

Deletes a passkey from a user.

Parameters

  • userId
    Required
    String

    User ID that owns the passkey.

  • passkeyId
    Required
    String

    ID of the passkey to delete.

1
await supabase.auth.admin.passkey.deletePasskey(
2
userId: '11111111-1111-1111-1111-111111111111',
3
passkeyId: '34e770dd-9ff9-416c-87fa-43b31d7ef225',
4
);

listPasskeys

Returns the list of passkeys registered to the user with the given ID.

Parameters

  • userId
    Required
    String

    User ID whose passkeys should be returned.

1
final List<Passkey> passkeys = await supabase.auth.admin.passkey.listPasskeys(
2
userId: '11111111-1111-1111-1111-111111111111',
3
);

invoke

Invokes a Supabase Function. See the guide for details on writing Functions.

  • Requires an Authorization header.
  • Invoke params generally match the Fetch API spec.

Parameters

  • functionName
    Required
    String

    The name of the function to invoke.

  • headers
    Optional
    Map<String, String>

    Custom headers to send with the request.

  • body
    Optional
    Map<String, String>

    The body of the request.

  • method
    Optional
    HttpMethod

    HTTP method of the request. Defaults to POST.

  • abortSignal
    Optional
    Future<void>

    Cancels the in-flight request when the provided Future completes. It must not complete with an error. On abort, an http.RequestAbortedException (from package:http) is thrown. Useful for cancelling a request in response to an event or for setting a request timeout.

1
final res = await supabase.functions.invoke('hello', body: {'foo': 'baa'});
2
final data = res.data;

getChannels

Returns all Realtime channels.

1
final channels = supabase.getChannels();

onHeartbeat

A Stream that emits a status every time the Realtime client sends a heartbeat, receives an acknowledgement, or when a heartbeat goes unanswered.

  • Each event is a RealtimeHeartbeatStatus: sent when a heartbeat is pushed, ok or error when the server acknowledges it, and timeout when a prior heartbeat is not answered in time.
  • Useful for observing connection health, for example to surface a reconnecting indicator in your UI.
1
final subscription = supabase.realtime.onHeartbeat.listen((status) {
2
print('Heartbeat status: $status');
3
});

removeAllChannels

Unsubscribes and removes all Realtime channels from Realtime client.

  • Removing channels is a great way to maintain the performance of your project's Realtime service as well as your database if you're listening to Postgres changes. Supabase will automatically handle cleanup 30 seconds after a client is disconnected, but unused channels may cause degradation as more clients are simultaneously subscribed.
1
final statuses = await supabase.removeAllChannels();

removeChannel

Unsubscribes and removes Realtime channel from Realtime client.

  • Removing a channel is a great way to maintain the performance of your project's Realtime service as well as your database if you're listening to Postgres changes. Supabase will automatically handle cleanup 30 seconds after a client is disconnected, but unused channels may cause degradation as more clients are simultaneously subscribed.
1
final status = await supabase.removeChannel(channel);

stream

Returns real-time data from your table as a Stream.

  • Realtime is disabled by default for new tables. You can turn it on by managing replication.
  • stream() will emit the initial data as well as any further change on the database as Stream<List<Map<String, dynamic>>> by combining Postgrest and Realtime.
  • Takes a list of primary key column names that will be used to update and delete the proper records within the SDK.
  • To use a private Realtime channel, pass channelOptions: const RealtimeChannelConfig(private: true) to the stream() call.
  • The following filters are available
    • .eq('column', value) listens to rows where the column equals the value
    • .neq('column', value) listens to rows where the column does not equal the value
    • .gt('column', value) listens to rows where the column is greater than the value
    • .gte('column', value) listens to rows where the column is greater than or equal to the value
    • .lt('column', value) listens to rows where the column is less than the value
    • .lte('column', value) listens to rows where the column is less than or equal to the value
    • .inFilter('column', [val1, val2, val3]) listens to rows where the column is one of the values
1
supabase.from('countries')
2
.stream(primaryKey: ['id'])
3
.listen((List<Map<String, dynamic>> data) {
4
// Do something awesome with the data
5
});

subscribe

Subscribe to realtime changes in your database.

  • Realtime is disabled by default for new tables. You can turn it on by managing replication.
  • If you want to receive the "previous" data for updates and deletes, you will need to set REPLICA IDENTITY to FULL, like this: ALTER TABLE your_table REPLICA IDENTITY FULL;
1
supabase
2
.channel('public:countries')
3
.onPostgresChanges(
4
event: PostgresChangeEvent.all,
5
schema: 'public',
6
table: 'countries',
7
callback: (payload) {
8
print('Change received: ${payload.toString()}');
9
})
10
.subscribe();

Analytics Buckets

This section contains methods for working with analytics buckets backed by Apache Iceberg.


analyticsCatalog

Returns an Iceberg REST Catalog client for an analytics bucket, used to manage the namespaces and tables (the warehouse) inside it.

  • Analytics buckets are backed by the Apache Iceberg table format.
  • analyticsCatalog() returns an IcebergRestCatalog scoped to a single analytics bucket. Use it to create and manage namespaces and tables within that bucket.
  • Refer to the Storage guide on how access control works

Parameters

  • bucketId
    Required
    String

    The identifier of the analytics bucket (the warehouse) whose namespaces and tables you want to manage.

  • accessDelegation
    Optional
    List<AccessDelegation>

    Requests server side access delegation for the catalog operations.

1
final catalog = supabase
2
.storage
3
.analyticsCatalog('my-analytics-bucket');
4
5
await catalog.createNamespace(['analytics']);

createAnalyticsBucket

Creates a new analytics bucket backed by the Apache Iceberg table format.

  • Policy permissions required:
    • buckets permissions: insert
    • objects permissions: none
  • Refer to the Storage guide on how access control works

Parameters

  • id
    Required
    String

    A unique identifier for the analytics bucket you are creating.

1
final AnalyticsBucket bucket = await supabase
2
.storage
3
.createAnalyticsBucket('warehouse');

deleteAnalyticsBucket

Deletes an existing analytics bucket. A bucket can't be deleted while it still contains namespaces or tables.

  • Policy permissions required:
    • buckets permissions: select and delete
    • objects permissions: none
  • Refer to the Storage guide on how access control works

Parameters

  • id
    Required
    String

    The unique identifier of the analytics bucket you would like to delete.

1
final String res = await supabase
2
.storage
3
.deleteAnalyticsBucket('warehouse');

listAnalyticsBuckets

Retrieves the details of all analytics buckets within an existing project.

  • Calling listAnalyticsBuckets() without any options returns all analytics buckets.
  • Policy permissions required:
    • buckets permissions: select
    • objects permissions: none
  • Refer to the Storage guide on how access control works

Parameters

  • options
    Optional
    ListBucketsOptions

    Optionally filter, sort and paginate the returned buckets.

1
final List<AnalyticsBucket> buckets = await supabase
2
.storage
3
.listAnalyticsBuckets();

File Buckets

This section contains methods for working with File Buckets.


createBucket

Creates a new Storage bucket

  • Policy permissions required:
    • buckets permissions: insert
    • objects permissions: none
  • Refer to the Storage guide on how access control works

Parameters

  • id
    Required
    String

    A unique identifier for the bucket you are creating.

  • bucketOptions
    Optional
    BucketOptions

    A parameter to optionally make the bucket public.

1
final String bucketId = await supabase
2
.storage
3
.createBucket('avatars');

createSignedUploadUrl

Creates a signed upload URL. Signed upload URLs can be used to upload files to a bucket without further authentication. They are valid for 2 hours.

  • Policy permissions required:
    • buckets permissions: none
    • objects permissions: insert
  • Refer to the Storage guide on how access control works

Parameters

  • path
    Required
    String

    The file path, including the current file name. For example folder/image.png.

  • upsert
    Optional
    bool

    If true, the signed URL allows overwriting an existing file at the path. Defaults to false.

1
final response = await supabase
2
.storage
3
.from('avatars')
4
.createSignedUploadUrl('folder/avatar1.png');

createSignedUrl

Create signed url to download file without requiring permissions. This URL can be valid for a set number of seconds.

  • Policy permissions required:
    • buckets permissions: none
    • objects permissions: select
  • Refer to the Storage guide on how access control works

Parameters

  • path
    Required
    String

    The file path, including the file name. For example folder/image.png.

  • expiresIn
    Required
    int

    The number of seconds until the signed URL expires. For example, 60 for a URL which is valid for one minute.

  • download
    Optional
    DownloadBehavior

    Triggers the file to be downloaded rather than opened in the browser. Use DownloadBehavior.withOriginalName to keep the original file name or DownloadBehavior.named('custom.png') to override it.

  • cacheNonce
    Optional
    String

    Appends a cacheNonce query parameter to the signed URL to bypass CDN caching for a specific file version.

  • transform
    Optional
    TransformOptions

    Transform the asset before serving it to the client.

1
final String signedUrl = await supabase
2
.storage
3
.from('avatars')
4
.createSignedUrl('avatar1.png', 60);

deleteBucket

Deletes an existing bucket. A bucket can't be deleted with existing objects inside it. You must first empty() the bucket.

  • Policy permissions required:
    • buckets permissions: select and delete
    • objects permissions: none
  • Refer to the Storage guide on how access control works

Parameters

  • id
    Required
    String

    A unique identifier for the bucket you are deleting.

1
final String res = await supabase
2
.storage
3
.deleteBucket('avatars');

download

Downloads a file.

  • Policy permissions required:
    • buckets permissions: none
    • objects permissions: select
  • Refer to the Storage guide on how access control works

Parameters

  • path
    Required
    String

    The full path and file name of the file to be downloaded. For example folder/image.png.

  • cacheNonce
    Optional
    String

    Adds a cacheNonce query parameter to bypass CDN caching for a specific file version.

  • transform
    Optional
    TransformOptions

    Transform the asset before serving it to the client.

1
final Uint8List file = await supabase
2
.storage
3
.from('avatars')
4
.download('avatar1.png');

downloadStream

Downloads a file as a lazy Stream<Uint8List>, streaming the bytes instead of buffering the whole file into memory like download().

  • The request is sent when the stream is listened to. A non-success response surfaces as a StorageException on the stream before any bytes are emitted.
  • Prefer this over download() for large files to keep memory usage low.
  • Policy permissions required:
    • buckets permissions: none
    • objects permissions: select
  • Refer to the Storage guide on how access control works

Parameters

  • path
    Required
    String

    The full path and file name of the file to be downloaded. For example folder/image.png.

  • cacheNonce
    Optional
    String

    Adds a cacheNonce query parameter to bypass CDN caching for a specific file version.

  • transform
    Optional
    TransformOptions

    Transform the asset before serving it to the client.

1
final Stream<Uint8List> stream = supabase
2
.storage
3
.from('avatars')
4
.downloadStream('avatar1.png');
5
6
await for (final chunk in stream) {
7
// Handle each chunk of bytes as it arrives
8
}

emptyBucket

Removes all objects inside a single bucket.

  • Policy permissions required:
    • buckets permissions: select
    • objects permissions: select and delete
  • Refer to the Storage guide on how access control works

Parameters

  • id
    Required
    String

    A unique identifier for the bucket you are emptying.

1
final String res = await supabase
2
.storage
3
.emptyBucket('avatars');

getBucket

Retrieves the details of an existing Storage bucket.

  • Policy permissions required:
    • buckets permissions: select
    • objects permissions: none
  • Refer to the Storage guide on how access control works

Parameters

  • id
    Required
    String

    The unique identifier of the bucket you would like to retrieve.

1
final Bucket bucket = await supabase
2
.storage
3
.getBucket('avatars');

getPublicUrl

Retrieve URLs for assets in public buckets

  • The bucket needs to be set to public, either via updateBucket() or by going to Storage on supabase.com/dashboard, clicking the overflow menu on a bucket and choosing "Make public"
  • Policy permissions required:
    • buckets permissions: none
    • objects permissions: none
  • Refer to the Storage guide on how access control works

Parameters

  • path
    Required
    String

    The path and name of the file to generate the public URL for. For example folder/image.png.

  • download
    Optional
    DownloadBehavior

    Triggers the file to be downloaded rather than opened in the browser. Use DownloadBehavior.withOriginalName to keep the original file name or DownloadBehavior.named('custom.png') to override it.

  • cacheNonce
    Optional
    String

    Appends a cacheNonce query parameter to the URL to bypass CDN caching for a specific file version.

  • transform
    Optional
    TransformOptions

    Transform the asset before serving it to the client.

1
final String publicUrl = supabase
2
.storage
3
.from('public-bucket')
4
.getPublicUrl('avatar1.png');

list

Lists all the files within a bucket.

  • Policy permissions required:
    • buckets permissions: none
    • objects permissions: select
  • Refer to the Storage guide on how access control works

Parameters

  • path
    Required
    String

    The folder path.

  • searchOptions
    Optional
    SearchOptions

    Options for the search operations such as limit and offset.

1
final List<FileObject> objects = await supabase
2
.storage
3
.from('avatars')
4
.list();

listBuckets

Retrieves the details of all Storage buckets within an existing product.

  • Policy permissions required:
    • buckets permissions: select
    • objects permissions: none
  • Refer to the Storage guide on how access control works

Parameters

  • options
    Optional
    ListBucketsOptions

    Optionally filter, sort and paginate the returned buckets. Calling listBuckets() without any options returns all buckets.

1
final List<Bucket> buckets = await supabase
2
.storage
3
.listBuckets();

listPaginated

Lists files and folders within a bucket with cursor-based pagination and hierarchical (delimiter) listing.

  • Folder entries in PaginatedListResult.folders only contain a name (and optionally a key). Full metadata is only available on the file entries in PaginatedListResult.objects.
  • To fetch the next page, pass the PaginatedListResult.nextCursor value from the previous request as PaginatedSearchOptions.cursor. Use PaginatedListResult.hasNext to check whether more results are available.
  • Policy permissions required:
    • buckets permissions: none
    • objects permissions: select
  • Refer to the Storage guide on how access control works

Parameters

  • options
    Optional
    PaginatedSearchOptions

    Options for the paginated search operation.

1
final PaginatedListResult result = await supabase
2
.storage
3
.from('avatars')
4
.listPaginated(
5
options: const PaginatedSearchOptions(
6
prefix: 'folder/',
7
limit: 100,
8
withDelimiter: true,
9
sortBy: FileSort(
10
column: FileSortColumn.createdAt,
11
order: FileSortOrder.descending,
12
),
13
),
14
);
15
16
for (final folder in result.folders) {
17
// Handle each folder
18
}
19
for (final object in result.objects) {
20
// Handle each file
21
}

move

Moves an existing file, optionally renaming it at the same time.

  • Policy permissions required:
    • buckets permissions: none
    • objects permissions: update and select
  • Refer to the Storage guide on how access control works

Parameters

  • fromPath
    Required
    String

    The original file path, including the current file name. For example folder/image.png.

  • toPath
    Required
    String

    The new file path, including the new file name. For example folder/image-new.png.

1
final String result = await supabase
2
.storage
3
.from('avatars')
4
.move('public/avatar1.png', 'private/avatar2.png');

purgeBucketCache

Invalidates the CDN cache for every object in a bucket.

  • Requires the secret key and the purgeCache feature enabled for your project on the storage server.
  • When transformations is true, only the resized/formatted variants are purged, leaving the original cached objects intact. Otherwise the bucket's object cache is purged.
  • Policy permissions required:
    • buckets permissions: select
    • objects permissions: none
  • Refer to the Storage guide on how access control works

Parameters

  • id
    Required
    String

    The unique identifier of the bucket whose CDN cache should be purged.

  • transformations
    Optional
    bool

    When true, only the transformed (resized/formatted) variants are purged, leaving the original cached objects intact. Defaults to false.

1
final String res = await supabase
2
.storage
3
.purgeBucketCache('avatars');

purgeCache

Invalidates the CDN cache for a single object in a bucket.

  • Requires the secret key and the purgeCache feature enabled for your project on the storage server.
  • When transformations is true, only the resized/formatted variants are purged, leaving the original cached object intact. Otherwise the object's cache is purged.
  • Policy permissions required:
    • buckets permissions: none
    • objects permissions: select
  • Refer to the Storage guide on how access control works

Parameters

  • path
    Required
    String

    The path and name of the object to purge from the CDN cache. For example folder/image.png.

  • transformations
    Optional
    bool

    When true, only the transformed (resized/formatted) variants are purged, leaving the original cached object intact. Defaults to false.

1
final String res = await supabase
2
.storage
3
.from('avatars')
4
.purgeCache('avatar1.png');

remove

Deletes files within the same bucket

  • Policy permissions required:
    • buckets permissions: none
    • objects permissions: delete and select
  • Refer to the Storage guide on how access control works

Parameters

  • paths
    Required
    List<String>

    A list of files to delete, including the path and file name. For example ['folder/image.png'].

1
final List<FileObject> objects = await supabase
2
.storage
3
.from('avatars')
4
.remove(['avatar1.png']);

update

Replaces an existing file at the specified path with a new one.

  • Policy permissions required:
    • buckets permissions: none
    • objects permissions: update and select
  • Refer to the Storage guide on how access control works

Parameters

  • path
    Required
    String

    The relative file path. Should be of the format folder/subfolder/filename.png. The bucket must already exist before attempting to update.

  • file
    Required
    File or Uint8List

    File object to be stored in the bucket.

  • fileOptions
    Optional
    FileOptions
  • retryAttempts
    Optional
    int

    Sets the retryAttempts parameter set across the storage client. Defaults to 10.

  • retryController
    Optional
    StorageRetryController

    Pass a RetryController instance and call cancel() to cancel the retry attempts.

1
final avatarFile = File('path/to/local/file');
2
final String path = await supabase.storage.from('avatars').update(
3
'public/avatar1.png',
4
avatarFile,
5
fileOptions: const FileOptions(cacheControl: '3600', upsert: false),
6
);

updateBucket

Updates a new Storage bucket

  • Policy permissions required:
    • buckets permissions: update
    • objects permissions: none
  • Refer to the Storage guide on how access control works

Parameters

  • id
    Required
    String

    A unique identifier for the bucket you are updating.

  • bucketOptions
    Required
    BucketOptions

    A parameter to optionally make the bucket public.

1
final String res = await supabase
2
.storage
3
.updateBucket('avatars', const BucketOptions(public: false));

upload

Uploads a file to an existing bucket.

  • Policy permissions required:
    • buckets permissions: none
    • objects permissions: insert
  • Refer to the Storage guide on how access control works

Parameters

  • path
    Required
    String

    The relative file path. Should be of the format folder/subfolder/filename.png. The bucket must already exist before attempting to update.

  • file
    Required
    File or Uint8List

    File object to be stored in the bucket.

  • fileOptions
    Optional
    FileOptions
  • retryAttempts
    Optional
    int

    Sets the retryAttempts parameter set across the storage client. Defaults to 10.

  • retryController
    Optional
    StorageRetryController

    Pass a RetryController instance and call cancel() to cancel the retry attempts.

1
final avatarFile = File('path/to/file');
2
final String fullPath = await supabase.storage.from('avatars').upload(
3
'public/avatar1.png',
4
avatarFile,
5
fileOptions: const FileOptions(cacheControl: '3600', upsert: false),
6
);

Vector Buckets

This section contains methods for working with Vector Buckets, invoked behind the supabase.storage.vectors namespace.


createBucket

Creates a new vector bucket. Access the vectors client through supabase.storage.vectors.

1
final vectors = supabase.storage.vectors;
2
3
await vectors.createBucket('embeddings');

createIndex

Creates a new vector index in the scoped bucket. dimension is the length of the vectors the index will store and distanceMetric is the metric used for similarity queries. Keys listed in nonFilterableMetadataKeys can be stored on vectors but not used in query filters. dataType defaults to VectorDataType.float32.

1
final bucket = supabase.storage.vectors.from('embeddings');
2
3
await bucket.createIndex(
4
name: 'documents',
5
dimension: 3,
6
distanceMetric: DistanceMetric.cosine,
7
);

deleteBucket

Deletes a vector bucket. The bucket must have no indexes before it can be deleted.

1
final vectors = supabase.storage.vectors;
2
3
await vectors.deleteBucket('embeddings');

deleteIndex

Deletes an index and all of its vectors from the scoped bucket.

1
final bucket = supabase.storage.vectors.from('embeddings');
2
3
await bucket.deleteIndex('documents');

deleteVectors

Deletes vectors by their keys. The batch must contain between 1 and 500 keys.

1
final index = supabase.storage.vectors
2
.from('embeddings')
3
.index('documents');
4
5
await index.deleteVectors(['doc-1', 'doc-2']);

from

Scopes index operations to a single vector bucket. Returns a StorageVectorBucketApi.

1
final bucket = supabase.storage.vectors.from('embeddings');
2
3
await bucket.createIndex(
4
name: 'documents',
5
dimension: 3,
6
distanceMetric: DistanceMetric.cosine,
7
);

getBucket

Retrieves the metadata of an existing vector bucket.

1
final vectors = supabase.storage.vectors;
2
3
final VectorBucket bucket = await vectors.getBucket('embeddings');

getIndex

Retrieves the metadata of an index in the scoped bucket.

1
final bucket = supabase.storage.vectors.from('embeddings');
2
3
final VectorIndex index = await bucket.getIndex('documents');
4
5
print(index.dimension);
6
print(index.distanceMetric);

getVectors

Retrieves vectors by their keys. Set returnData and returnMetadata to include the embeddings and metadata in the result. Keys that do not exist are omitted from the returned list.

1
final index = supabase.storage.vectors
2
.from('embeddings')
3
.index('documents');
4
5
final List<VectorMatch> vectors = await index.getVectors(
6
keys: ['doc-1', 'doc-2'],
7
returnData: true,
8
returnMetadata: true,
9
);
10
11
for (final vector in vectors) {
12
print('${vector.key}: ${vector.metadata}');
13
}

index

Scopes vector data operations to a single index within a bucket. Returns a StorageVectorIndexApi.

1
final bucket = supabase.storage.vectors.from('embeddings');
2
3
final index = bucket.index('documents');
4
5
await index.putVectors([
6
Vector(key: 'doc-1', data: [0.1, 0.2, 0.3]),
7
]);

listBuckets

Lists vector buckets. Use prefix to filter by name and maxResults / nextToken to paginate.

1
final vectors = supabase.storage.vectors;
2
3
final VectorBucketList result = await vectors.listBuckets();
4
5
for (final bucket in result.buckets) {
6
print(bucket.name);
7
}

listIndexes

Lists indexes in the scoped bucket. Use prefix to filter by name and maxResults / nextToken to paginate.

1
final bucket = supabase.storage.vectors.from('embeddings');
2
3
final VectorIndexList result = await bucket.listIndexes();
4
5
for (final index in result.indexes) {
6
print(index.name);
7
}

listVectors

Lists vectors in the scoped index with pagination. A full-index scan can be distributed across multiple workers by giving each worker a different segmentIndex (0 to segmentCount - 1) for the same segmentCount (1 to 16).

1
final index = supabase.storage.vectors
2
.from('embeddings')
3
.index('documents');
4
5
final VectorList result = await index.listVectors(
6
maxResults: 100,
7
returnMetadata: true,
8
);
9
10
for (final vector in result.vectors) {
11
print(vector.key);
12
}

putVectors

Inserts or updates a batch of vectors in the scoped index. The batch must contain between 1 and 500 vectors, and each vector's data length must match the index dimension.

1
final index = supabase.storage.vectors
2
.from('embeddings')
3
.index('documents');
4
5
await index.putVectors([
6
Vector(
7
key: 'doc-1',
8
data: [0.1, 0.2, 0.3],
9
metadata: {'title': 'Intro'},
10
),
11
Vector(
12
key: 'doc-2',
13
data: [0.4, 0.5, 0.6],
14
metadata: {'title': 'Guide'},
15
),
16
]);

queryVectors

Searches the scoped index for the vectors most similar to queryVector. topK limits the number of matches returned. filter restricts the search to vectors whose metadata matches the given expression. Set returnDistance and returnMetadata to include the distance scores and metadata in the result.

1
final index = supabase.storage.vectors
2
.from('embeddings')
3
.index('documents');
4
5
final VectorQueryResult result = await index.queryVectors(
6
queryVector: [0.1, 0.2, 0.3],
7
topK: 5,
8
returnDistance: true,
9
returnMetadata: true,
10
);
11
12
for (final match in result.matches) {
13
print('${match.key}: ${match.distance}');
14
}