Flutter Client Library
supabase_flutterView on GitHubThis 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
1flutter pub add supabase_flutter
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
- urlRequiredstring
The unique Supabase URL which is supplied when you create a new project in your project dashboard.
- anonKeyRequiredstring
The unique Supabase Key which is supplied when you create a new project in your project dashboard.
- headersOptionalMap<String, String>
Custom header to be passed to the Supabase client.
- httpClientOptionalClient
Custom http client to be used by the Supabase client.
- authOptionsOptionalFlutterAuthClientOptions
Options to change the Auth behaviors.
- postgrestOptionsOptionalPostgrestClientOptions
Options to change the Postgrest behaviors.
- realtimeClientOptionsOptionalRealtimeClientOptions
Options to change the Realtime behaviors.
- storageOptionsOptionalStorageClientOptions
Options to change the Storage behaviors.
1234567891011Future<void> main() async { await Supabase.initialize( url: 'https://xyzcompany.supabase.co', anonKey: 'public-anon-key', ); runApp(MyApp());}// Get a reference your Supabase clientfinal 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.
1supabase_flutter: ^2.0.0
Optionally passing custom configuration to Supabase.initialize()
is now organized into separate objects:
123456789await Supabase.initialize( url: supabaseUrl, anonKey: supabaseKey, authFlowType: AuthFlowType.pkce, storageRetryAttempts: 10, realtimeClientOptions: const RealtimeClientOptions( logLevel: RealtimeLogLevel.info, ),);
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.
123await supabase.auth.signInWithOAuth( Provider.google,);
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.
1await 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.
12// Session is valid, no check requiredfinal 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.
123456// Opens a webview on iOS.await supabase.auth.signInWithOAuth( Provider.github, authScreenLaunchMode: LaunchMode.inAppWebView, context: context,);
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.
12345await Supabase.initialize( url: 'SUPABASE_URL', anonKey: 'SUPABASE_ANON_KEY', authFlowType: AuthFlowType.implicit, // set to implicit by default);
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.
12345await Supabase.initialize( url: 'SUPABASE_URL', anonKey: 'SUPABASE_ANON_KEY', authCallbackUrlHostname: 'auth-callback',);
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.
12// Use `initialSession` to obtain the initial session when the app starts.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.
1234567// If you declare a query and chain filters on itfinal myQuery = supabase.from('my_table').select();final foo = await myQuery.eq('some_col', 'foo');// The `eq` filter above is applied in addition to the following filterfinal 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
.
123456789final data = await supabase .from('users') .select() .is_('status', null);final data = await supabase .from('users') .select() .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.
12345678910111213141516171819202122// Request with count optionfinal res = await supabase.from('cities').select( 'name', const FetchOptions( count: CountOption.exact, ), );final data = res.data;final count = res.count;// Request with count and head option// obtains the count value without fetching the data.final res = await supabase.from('cities').select( 'name', const FetchOptions( count: CountOption.exact, head: true, ), );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.
12345try { await supabase.from('countries').select();} on PostgrestException catch (error) { error.code; // Contains http status code}
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.
12345678910111213supabase.channel('my_channel').on( RealtimeListenTypes.postgresChanges, ChannelFilter( event: '*', schema: 'public', table: 'messages', filter: 'room_id=eq.200', ), (dynamic payload, [ref]) { final Map<String, dynamic> newRecord = payload['new']; final Map<String, dynamic> oldRecord = payload['old']; },).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.
123456789supabase.channel('my_channel').on( RealtimeListenTypes.broadcast, ChannelFilter( event: 'position', ), (dynamic payload, [ref]) { print(payload); },).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.
123456789101112131415161718192021222324252627final channel = supabase.channel('room1');channel.on( RealtimeListenTypes.presence, ChannelFilter(event: 'sync'), (payload, [ref]) { print('Synced presence state: ${channel.presenceState()}'); },).on( RealtimeListenTypes.presence, ChannelFilter(event: 'join'), (payload, [ref]) { print('Newly joined presences $payload'); },).on( RealtimeListenTypes.presence, ChannelFilter(event: 'leave'), (payload, [ref]) { print('Newly left presences: $payload'); },).subscribe( (status, [error]) async { if (status == 'SUBSCRIBED') { await channel.track({'online_at': DateTime.now().toIso8601String()}); } },);
Fetch data
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 Filtersselect()
can be combined with Modifiersapikey
is a reserved keyword if you're using the Supabase Platform and should be avoided as a column name.
Parameters
- columnsOptionalString
The columns to retrieve, separated by commas. Columns can be renamed when returned with
customName:columnName
123final data = await supabase .from('instruments') .select();
Insert data
Perform an INSERT into the table or view.
Parameters
- valuesRequiredMap<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.
123await supabase .from('cities') .insert({'name': 'The Shire', 'country_id': 554});
Update data
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
- valuesRequiredMap<String, dynamic>
The values to update with.
1234await supabase .from('instruments') .update({ 'name': 'piano' }) .eq('id', 1);
Upsert data
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
- valuesRequiredMap<String, dynamic> or List<Map<String, dynamic>>
The values to upsert with. Pass a Map to upsert a single row or an List to upsert multiple rows.
- onConflictOptionalString
Comma-separated UNIQUE column(s) to specify how duplicate rows are determined. Two rows are duplicates if all the
onConflict
columns are equal. - ignoreDuplicatesOptionalbool
If
true
, duplicate rows are ignored. Iffalse
, duplicate rows are merged with existing rows. - defaultToNullOptionalbool
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.
1234final data = await supabase .from('instruments') .upsert({ 'id': 1, 'name': 'piano' }) .select();
Delete data
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 throughSELECT
policies are deleted. Note that by default no rows are visible, so you need at least oneSELECT
/ALL
policy that makes the rows visible.
1234await supabase .from('countries') .delete() .eq('id', 1);
Call a Postgres function
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
- fnRequiredString
The function name to call.
- paramsOptionalMap<String, dynamic>
The arguments to pass to the function call.
12final data = await supabase .rpc('hello_world');
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.
123456789final data = await supabase .from('cities') .select('name, country_id') .eq('name', 'The Shire'); // Correctfinal data = await supabase .from('cities') .eq('name', 'The Shire') // Incorrect .select('name, country_id');
Column is equal to a value
Match only rows where column
is equal to value
.
Parameters
- columnRequiredString
The column to filter on.
- valueRequiredObject
The value to filter with.
1234final data = await supabase .from('instruments') .select() .eq('name', 'viola');
Column is not equal to a value
Finds all rows whose value on the stated column
doesn't match the specified value
.
Parameters
- columnRequiredString
The column to filter on.
- valueRequiredObject
The value to filter with.
1234final data = await supabase .from('instruments') .select('id, name') .neq('name', 'viola');
Column is greater than a value
Finds all rows whose value on the stated column
is greater than the specified value
.
Parameters
- columnRequiredString
The column to filter on.
- valueRequiredObject
The value to filter with.
1234final data = await supabase .from('countries') .select() .gt('id', 2);
Column is greater than or equal to a value
Finds all rows whose value on the stated column
is greater than or equal to the specified value
.
Parameters
- columnRequiredString
The column to filter on.
- valueRequiredObject
The value to filter with.
1234final data = await supabase .from('countries') .select() .gte('id', 2);
Column is less than a value
Finds all rows whose value on the stated column
is less than the specified value
.
Parameters
- columnRequiredString
The column to filter on.
- valueRequiredObject
The value to filter with.
1234final data = await supabase .from('countries') .select() .lt('id', 2);
Column is less than or equal to a value
Finds all rows whose value on the stated column
is less than or equal to the specified value
.
Parameters
- columnRequiredString
The column to filter on.
- valueRequiredObject
The value to filter with.
1234final data = await supabase .from('countries') .select() .lte('id', 2);
Column matches a pattern
Finds all rows whose value in the stated column
matches the supplied pattern
(case sensitive).
Parameters
- columnRequiredString
The column to filter on.
- patternRequiredString
The pattern to match with.
1234final data = await supabase .from('planets') .select() .like('name', '%Ea%');
Column matches a case-insensitive pattern
Finds all rows whose value in the stated column
matches the supplied pattern
(case insensitive).
Parameters
- columnRequiredString
The column to filter on.
- patternRequiredString
The pattern to match with.
1234final data = await supabase .from('planets') .select() .ilike('name', '%ea%');
Column is a value
A check for exact equality (null, true, false), finds all rows whose value on the stated column
exactly match the specified value
.
Parameters
- columnRequiredString
The column to filter on.
- valueRequiredObject?
The value to filter with.
1234final data = await supabase .from('countries') .select() .isFilter('name', null);
Column is in an array
Finds all rows whose value on the stated column
is found on the specified values
.
Parameters
- columnRequiredString
The column to filter on.
- valuesRequiredList
The List to filter with.
1234final data = await supabase .from('characters') .select() .inFilter('name', ['Luke', 'Leia']);
Column contains every element in a value
Only relevant for jsonb, array, and range columns. Match only rows where column
contains every element appearing in value
.
Parameters
- columnRequiredString
The jsonb, array, or range column to filter on.
- valueRequiredObject
The jsonb, array, or range value to filter with.
1234final data = await supabase .from('issues') .select() .contains('tags', ['is:open', 'priority:low']);
Contained by value
Only relevant for jsonb, array, and range columns. Match only rows where every element appearing in column
is contained by value
.
Parameters
- columnRequiredString
The jsonb, array, or range column to filter on.
- valueRequiredObject
The jsonb, array, or range value to filter with.
1234final data = await supabase .from('classes') .select('name') .containedBy('days', ['monday', 'tuesday', 'wednesday', 'friday']);
Greater than a range
Only relevant for range columns. Match only rows where every element in column
is greater than any element in range
.
Parameters
- columnRequiredString
The range column to filter on.
- rangeRequiredString
The range to filter with.
1234final data = await supabase .from('reservations') .select() .rangeGt('during', '[2000-01-02 08:00, 2000-01-02 09:00)');
Greater than or equal to a range
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
- columnRequiredString
The range column to filter on.
- rangeRequiredString
The range to filter with.
1234final data = await supabase .from('reservations') .select() .rangeGte('during', '[2000-01-02 08:30, 2000-01-02 09:30)');
Less than a range
Only relevant for range columns. Match only rows where every element in column
is less than any element in range
.
Parameters
- columnRequiredString
The range column to filter on.
- rangeRequiredString
The range to filter with.
1234final data = await supabase .from('reservations') .select() .rangeLt('during', '[2000-01-01 15:00, 2000-01-01 16:00)');
Less than or equal to a range
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
- columnRequiredString
The range column to filter on.
- rangeRequiredString
The range to filter with.
1234final data = await supabase .from('reservations') .select() .rangeLte('during', '[2000-01-01 15:00, 2000-01-01 16:00)');
Mutually exclusive to a range
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
- columnRequiredString
The range column to filter on.
- rangeRequiredString
The range to filter with.
1234final data = await supabase .from('reservations') .select() .rangeAdjacent('during', '[2000-01-01 12:00, 2000-01-01 13:00)');
With a common element
Only relevant for array and range columns. Match only rows where column
and value
have an element in common.
Parameters
- columnRequiredString
The array or range column to filter on.
- valueRequiredObject
The array or range value to filter with.
1234final data = await supabase .from('issues') .select('title') .overlaps('tags', ['is:closed', 'severity:high']);
Match a string
Finds all rows whose tsvector value on the stated column
matches to_tsquery(query).
Parameters
- columnRequiredString
The text or tsvector column to filter on.
- queryRequiredString
The query text to match with.
- configOptionalString
The text search configuration to use.
- typeOptionalTextSearchType
Change how the
query
text is interpreted.
123456final data = await supabase .from('quotes') .select('catchphrase') .textSearch('content', "'eggs' & 'ham'", config: 'english' );
Match an associated value
Finds all rows whose columns match the specified query
object.
Parameters
- queryRequiredMap<String, dynamic>
The object to filter with, with column names as keys mapped to their filter values
1234final data = await supabase .from('instruments') .select() .match({ 'id': 2, 'name': 'viola' });
Don't match the filter
Finds all rows which doesn't satisfy the filter.
-
.not()
expects you to use the raw PostgREST syntax for the filter names and values.12345.not('name','eq','violin').not('arraycol','cs','{"a","b"}') // Use Postgres array {} for array column and 'cs' for contains..not('rangecol','cs','(1,2]') // Use Postgres range syntax for range column..not('id','in','(6,7)') // Use Postgres list () and 'in' instead of `inFilter`..not('id','in','(${mylist.join(',')})') // You can insert a Dart list array.
Parameters
- columnRequiredString
The column to filter on.
- operatorRequiredString
The operator to be negated to filter with, following PostgREST syntax.
- valueOptionalObject
The value to filter with, following PostgREST syntax.
1234final data = await supabase .from('countries') .select() .not('name', 'is', null)
Match at least one filter
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.123.or('id.in.(6,7),arraycol.cs.{"a","b"}') // Use Postgres list () and 'in' instead of `inFilter`. Array {} and 'cs' for contains..or('id.in.(${mylist.join(',')}),arraycol.cs.{${mylistArray.join(',')}}') // You can insert a Dart list for list or array column..or('id.in.(${mylist.join(',')}),rangecol.cs.(${mylistRange.join(',')}]') // You can insert a Dart list for list or range column.
Parameters
- filtersRequiredString
The filters to use, following PostgREST syntax
- referencedTableOptionalString
Set this to filter on referenced tables instead of the parent table
1234final data = await supabase .from('instruments') .select('name') .or('id.eq.2,name.eq.cello');
Match the 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.
1234.filter('arraycol','cs','{"a","b"}') // Use Postgres array {} and 'cs' for contains..filter('rangecol','cs','(1,2]') // Use Postgres range syntax for range column..filter('id','in','(6,7)') // Use Postgres list () and 'in' for in_ filter..filter('id','cs','{${mylist.join(',')}}') // You can insert a Dart array list.
Parameters
- columnRequiredString
The column to filter on.
- operatorRequiredString
The operator to filter with, following PostgREST syntax.
- valueRequiredObject
The value to filter with, following PostgREST syntax.
1234final data = await supabase .from('characters') .select() .filter('name', 'in', '("Ron","Dumbledore")')
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).
Return data after inserting
1234final data = await supabase .from('instruments') .upsert({ 'id': 1, 'name': 'piano' }) .select();
Order the results
Orders the result with the specified column.
Parameters
- columnRequiredString
The column to order by.
- ascendingOptionalbool
Whether to order in ascending order. Default is
false
. - nullsFirstOptionalbool
Whether to order nulls first. Default is
false
. - referencedTableOptionalString
Specify the referenced table when ordering by a column in an embedded resource.
1234final data = await supabase .from('instruments') .select('id, name') .order('id', ascending: false);
Limit the number of rows returned
Limits the result with the specified count.
Parameters
- countRequiredint
The maximum number of rows to return.
- referencedTableOptionalint
Set this to limit rows of referenced tables instead of the parent table.
1234final data = await supabase .from('instruments') .select('name') .limit(1);
Limit the query to a range
Limits the result to rows within the specified range, inclusive.
Parameters
- fromRequiredint
The starting index from which to limit the result.
- toRequiredint
The last index to which to limit the result.
- referencedTableOptionalString
Set this to limit rows of referenced tables instead of the parent table.
1234final data = await supabase .from('instruments') .select('name') .range(0, 1);
Retrieve one row of data
Retrieves only one row from the result. Result must be one row (e.g. using limit), otherwise this will result in an error.
12345final data = await supabase .from('instruments') .select('name') .limit(1) .single();
Retrieve zero or one row of data
12345final data = await supabase .from('instruments') .select() .eq('name', 'guzheng') .maybeSingle();
Retrieve as a CSV
1234final data = await supabase .from('instruments') .select() .csv();
Using 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
- analyzeOptionalbool
If
true
, the query will be executed and the actual run time will be returned. - verboseOptionalbool
If
true
, the query identifier will be returned anddata
will include the output columns of the query. - settingsOptionalbool
If
true
, include information on configuration parameters that affect query planning. - buffersOptionalbool
If
true
, include information on buffer usage. - walOptionalbool
If
true
, include information on WAL record generation.
1234final data = await supabase .from('instruments') .select() .explain();
Create a new user
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 butsession
is null. - If Confirm email is disabled, both a
user
and asession
are returned.
- If Confirm email is enabled, a
- When the user confirms their email address, they are redirected to the
SITE_URL
by default. You can modify yourSITE_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
- emailOptionalString
User's email address to be used for email authentication.
- phoneOptionalString
User's phone number to be used for phone authentication.
- passwordRequiredString
Password to be used for authentication.
- emailRedirectToOptionalString
The URL to redirect the user to after they confirm their email address.
- dataOptionalMap<String, dynamic>
The user's metadata to be stored in the user's object.
- captchaTokenOptionalString
The captcha token to be used for captcha verification.
- channelOptionalOtpChannel
Messaging channel to use (e.g. whatsapp or sms). Defaults to
OtpChannel.sms
.
123456final AuthResponse res = await supabase.auth.signUp( email: '[email protected]', password: 'example-password',);final Session? session = res.session;final User? user = res.user;
Listen to auth events
Receive a notification every time an auth event happens.
- Types of auth events:
AuthChangeEvent.passwordRecovery
,AuthChangeEvent.signedIn
,AuthChangeEvent.signedOut
,AuthChangeEvent.tokenRefreshed
,AuthChangeEvent.userUpdated
andAuthChangeEvent.userDeleted
12345678910111213141516171819202122232425final authSubscription = supabase.auth.onAuthStateChange.listen((data) { final AuthChangeEvent event = data.event; final Session? session = data.session; print('event: $event, session: $session'); switch (event) { case AuthChangeEvent.initialSession: // handle initial session case AuthChangeEvent.signedIn: // handle signed in case AuthChangeEvent.signedOut: // handle signed out case AuthChangeEvent.passwordRecovery: // handle password recovery case AuthChangeEvent.tokenRefreshed: // handle token refreshed case AuthChangeEvent.userUpdated: // handle user updated case AuthChangeEvent.userDeleted: // handle user deleted case AuthChangeEvent.mfaChallengeVerified: // handle mfa challenge verified }});
Create an anonymous user
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
- dataOptionalMap<String, dynamic>
The user's metadata to be stored in the user's object.
- captchaTokenOptionalString
The captcha token to be used for captcha verification.
1await supabase.auth.signInAnonymously();
Sign in a user
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
- emailOptionalString
User's email address to be used for email authentication.
- phoneOptionalString
User's phone number to be used for phone authentication.
- passwordRequiredString
Password to be used for authentication.
- captchaTokenOptionalString
The captcha token to be used for captcha verification.
123456final AuthResponse res = await supabase.auth.signInWithPassword( email: '[email protected]', password: 'example-password',);final Session? session = res.session;final User? user = res.user;
Sign in with ID Token
Allows you to perform native Google and Apple sign in by combining it with google_sign_in or sign_in_with_apple packages.
Parameters
- providerRequiredOAuthProvider
The provider to perform the sign in with. Currently,
OAuthProvider.google
andOAuthProvider.apple
are supported. - idTokenRequiredString
The identity token obtained from the third-party provider.
- accessTokenOptionalString
Access token obtained from the third-party provider. Required for Google sign in.
- nonceOptionalString
Raw nonce value used to perform the third-party sign in. Required for Apple sign-in.
- captchaTokenOptionalString
The captcha token to be used for captcha verification.
12345678910111213141516171819202122232425262728import 'package:google_sign_in/google_sign_in.dart';import 'package:supabase_flutter/supabase_flutter.dart';const webClientId = '<web client ID that you registered on Google Cloud, for example my-web.apps.googleusercontent.com>';const iosClientId = '<iOS client ID that you registered on Google Cloud, for example my-ios.apps.googleusercontent.com';final GoogleSignIn googleSignIn = GoogleSignIn( clientId: iosClientId, serverClientId: webClientId,);final googleUser = await googleSignIn.signIn();final googleAuth = await googleUser!.authentication;final accessToken = googleAuth.accessToken;final idToken = googleAuth.idToken;if (accessToken == null) { throw 'No Access Token found.';}if (idToken == null) { throw 'No ID Token found.';}final response = await supabase.auth.signInWithIdToken( provider: OAuthProvider.google, idToken: idToken, accessToken: accessToken,);
Sign in a user through OTP
- 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 theSITE_URL
or add additional redirect urls in your project.
Parameters
- emailOptionalString
Email address to send the magic link or OTP to.
- phoneOptionalString
Phone number to send the OTP to.
- emailRedirectToOptionalString
The URL to redirect the user to after they click on the magic link.
- shouldCreateUserOptionalbool
If set to false, this method will not create a new user. Defaults to true.
- dataOptionalMap<String, dynamic>
The user's metadata to be stored in the user's object.
- captchaTokenOptionalString
The captcha token to be used for captcha verification.
- channelOptionalOtpChannel
Messaging channel to use (e.g. whatsapp or sms). Defaults to
OtpChannel.sms
.
1234await supabase.auth.signInWithOtp( email: '[email protected]', emailRedirectTo: kIsWeb ? null : 'io.supabase.flutter://signin-callback/',);
Sign in a user through OAuth
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
- providerRequiredOAuthProvider
The OAuth provider to use for signing in.
- redirectToOptionalString
The URL to redirect the user to after they sign in with the third-party provider.
- scopesOptionalString
A list of scopes to request from the third-party provider.
- authScreenLaunchModeOptionalLaunchMode
The launch mode for the auth screen. Defaults to
LaunchMode.platformDefault
. - queryParamsOptionalMap<String, String>
Additional query parameters to be passed to the OAuth flow.
123456await supabase.auth.signInWithOAuth( OAuthProvider.github, redirectTo: kIsWeb ? null : 'my.scheme://my-host', // Optionally set the redirect link to bring back the user via deeplink. authScreenLaunchMode: kIsWeb ? LaunchMode.platformDefault : LaunchMode.externalApplication, // Launch the auth screen in a new webview on mobile.);
Sign in a user through SSO
- 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
- providerIdOptionalString
The ID of the SSO provider to use for signing in.
- domainOptionalString
The email domain to use for signing in.
- redirectToOptionalString
The URL to redirect the user to after they sign in with the third-party provider.
- captchaTokenOptionalString
The captcha token to be used for captcha verification.
- launchModeOptionalLaunchMode
The launch mode for the auth screen. Defaults to
LaunchMode.platformDefault
.
123await supabase.auth.signInWithSSO( domain: 'company.com',);
Sign out a user
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
- scopeOptionalSignOutScope
Whether to sign out from all devices or just the current device. Defaults to
SignOutScope.local
.
1await supabase.auth.signOut();
Verify and log in through OTP
- The
verifyOtp
method takes in different verification types. If a phone number is used, the type can either besms
orphone_change
. If an email address is used, the type can be one of the following:signup
,magiclink
,recovery
,invite
oremail_change
. - 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
- tokenRequiredString
The token that user was sent to their email or mobile phone
- typeRequiredOtpType
Type of the OTP to verify
- emailOptionalString
Email address that the OTP was sent to
- phoneOptionalString
Phone number that the OTP was sent to
- redirectToOptionalString
URI to redirect the user to after the OTP is verified
- captchaTokenOptionalString
The captcha token to be used for captcha verification
- tokenHashOptionalString
Token used in an email link
1234567final AuthResponse res = await supabase.auth.verifyOTP( type: OtpType.signup, token: token, phone: '+13334445555',);final Session? session = res.session;final User? user = res.user;
Retrieve a session
Returns the session data, if there is an active session.
1final Session? session = supabase.auth.currentSession;
Retrieve a new session
- This method will refresh and return a new session whether the current one is expired or not.
12final AuthResponse res = await supabase.auth.refreshSession();final session = res.session;
Retrieve a user
Returns the user data, if there is a logged in user.
1final User? user = supabase.auth.currentUser;
Update a user
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
- attributesRequiredUserAttributes
Attributes to update for the user.
- emailRedirectToOptionalString
The URI to redirect the user to after the email is updated.
123456final UserResponse res = await supabase.auth.updateUser( UserAttributes( email: '[email protected]', ),);final User? updatedUser = res.user;
Retrieve identities linked to a user
Gets all the identities linked to a user.
- The user needs to be signed in to call
getUserIdentities()
.
1final identities = await supabase.auth.getUserIdentities();
Link an identity to a user
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
- providerRequiredOAuthProvider
The provider to link the identity to.
- redirectToOptionalString
The URL to redirect the user to after they sign in with the third-party provider.
- scopesOptionalString
A list of scopes to request from the third-party provider.
- authScreenLaunchModeOptionalLaunchMode
The launch mode for the auth screen. Defaults to
LaunchMode.platformDefault
. - queryParamsOptionalMap<String, String>
Additional query parameters to be passed to the OAuth flow.
1await supabase.auth.linkIdentity(OAuthProvider.google);
Unlink an identity from a user
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
- identityRequiredUserIdentity
The user identity to unlink.
12345678910// retrieve all identites linked to a userfinal identities = await supabase.auth.getUserIdentities();// find the google identityfinal googleIdentity = identities.firstWhere( (element) => element.provider == 'google',);// unlink the google identityawait supabase.auth.unlinkIdentity(googleIdentity);
Send a password reauthentication nonce
- 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.
1await supabase.auth.reauthenticate();
Resend an OTP
- 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.
1234final ResendResponse res = await supabase.auth.resend( type: OtpType.signup, email: '[email protected]',);
Set the session data
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
- refreshTokenRequiredString
Refresh token to use to get a new session.
1234final refreshToken = supabase.currentSession?.refreshToken ?? '';final AuthResponse response = await supabase.auth.setSession(refreshToken);final session = res.session;
Auth MFA
This section contains methods commonly used for Multi-Factor Authentication (MFA) and are invoked behind the supabase.auth.mfa
namespace.
Currently, we only support time-based one-time password (TOTP) as the 2nd factor. We don't support recovery codes but we allow users to enroll more than 1 TOTP factor, with an upper limit of 10.
Having a 2nd TOTP factor for recovery means the user doesn't have to store their recovery codes. It also reduces the attack surface since the recovery factor is usually time-limited and not a single static code.
Learn more about implementing MFA on your application on our guide here.
Enroll a factor
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.
- Currently,
totp
is the only supportedfactorType
. The returnedid
should be used to create a challenge. - To create a challenge, see
mfa.challenge()
. - To verify a challenge, see
mfa.verify()
. - To create and verify a challenge in a single step, see
mfa.challengeAndVerify()
.
Parameters
- factorTypeOptionalString
Type of factor being enrolled.
- issuerOptionalString
Domain which the user is enrolled with.
- friendlyNameOptionalString
Human readable name assigned to the factor.
123final res = await supabase.auth.mfa.enroll(factorType: FactorType.totp);final qrCodeUrl = res.totp.qrCode;
Create a challenge
Prepares a challenge used to verify that a user has access to a MFA factor.
- An enrolled factor is required before creating a challenge.
- To verify a challenge, see
mfa.verify()
.
Parameters
- factorIdRequiredString
System assigned identifier for authenticator device as returned by enroll
123final res = await supabase.auth.mfa.challenge( factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225',);
Verify a challenge
Verifies a code against a challenge. The verification code is provided by the user by entering a code seen in their authenticator app.
- To verify a challenge, please create a challenge first.
Parameters
- factorIdRequiredString
System assigned identifier for authenticator device as returned by enroll
- challengeIdRequiredString
The ID of the challenge to verify
- codeRequiredString
The verification code on the user's authenticator app
12345final res = await supabase.auth.mfa.verify( factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225', challengeId: '4034ae6f-a8ce-4fb5-8ee5-69a5863a7c15', code: '123456',);
Create and verify a challenge
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.
- An enrolled factor is required before invoking
challengeAndVerify()
. - Executes
mfa.challenge()
andmfa.verify()
in a single step.
Parameters
- factorIdRequiredString
System assigned identifier for authenticator device as returned by enroll
- codeRequiredString
The verification code on the user's authenticator app
1234final res = await supabase.auth.mfa.challengeAndVerify( factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225', code: '123456',);
Unenroll a factor
Unenroll removes a MFA factor. A user has to have an aal2
authenticator level in order to unenroll a verified
factor.
Parameters
- factorIdRequiredString
System assigned identifier for authenticator device as returned by enroll
123final res = await supabase.auth.mfa.unenroll( '34e770dd-9ff9-416c-87fa-43b31d7ef225',);
Get Authenticator Assurance Level
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 ofaal2
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 returnsaal2
. Otherwise, it returnsaal1
.
1234final res = supabase.auth.mfa.getAuthenticatorAssuranceLevel();final currentLevel = res.currentLevel;final nextLevel = res.nextLevel;final currentAuthenticationMethods = res.currentAuthenticationMethods;
Auth Admin
- Any method under the
supabase.auth.admin
namespace requires aservice_role
key. - These methods are considered admin methods and should be called on a trusted server. Never expose your
service_role
key in the Flutter app.
1final supabase = SupabaseClient(supabaseUrl, serviceRoleKey);
Retrieve a user
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 theauth.users.id
column.
Parameters
- uidRequiredString
User ID of the user to fetch.
12final res = await supabase.auth.admin.getUserById(userId);final user = res.user;
List all users
Get a list of users.
- Defaults to return 50 users per page.
Parameters
- pageOptionalint
What page of users to return.
- pageOptionalint
How many users to be returned per page. Defaults to 50.
12// Returns the first 50 users.final List<User> users = await supabase.auth.admin.listUsers();
Create a user
Creates a new user.
- To confirm the user's email address or phone number, set
email_confirm
orphone_confirm
to true. Both arguments default to false. createUser()
will not send a confirmation email to the user. You can useinviteUserByEmail()
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
orphone_confirm
param totrue
.
Parameters
- attributesRequiredAdminUserAttributes
Attributes to create the user with.
12345final res = await supabase.auth.admin.createUser(AdminUserAttributes( email: '[email protected]', password: 'password', userMetadata: {'name': 'Yoda'},));
Delete a user
Delete a user.
- The
deleteUser()
method requires the user's ID, which maps to theauth.users.id
column.
Parameters
- idRequiredString
ID of the user to be deleted.
12await supabase.auth.admin .deleteUser('715ed5db-f090-4b8c-a067-640ecee36aa0');
Send an email invite link
Sends an invite link to the user's email address.
Parameters
- emailRequiredString
Email address of the user to invite.
- redirectToOptionalString
URI to redirect the user to after they open the invite link.
- dataOptionalMap<String, dynamic>
A custom data object to store the user's metadata. This maps to the
auth.users.user_metadata
column.
123final UserResponse res = await supabase.auth.admin .inviteUserByEmail('[email protected]');final User? user = res.user;
Generate an email link
Generates email links and OTPs to be sent via a custom email provider.
- The following types can be passed into
generateLink()
:signup
,magiclink
,invite
,recovery
,emailChangeCurrent
,emailChangeNew
,phoneChange
. generateLink()
only generates the email link foremail_change_email
if the "Secure email change" setting is enabled under the "Email" provider in your Supabase project.generateLink()
handles the creation of the user forsignup
,invite
andmagiclink
.
Parameters
- typeRequiredGenerateLinkType
The type of invite link to generate.
- emailRequiredString
Email address of the user to invite.
- passwordOptionalString
Password for the user. Required for
signup
type. - redirectToOptionalString
URI to redirect the user to after they open the invite link.
- dataOptionalMap<String, dynamic>
A custom data object to store the user's metadata. This maps to the
auth.users.user_metadata
column.
123456final res = await supabase.auth.admin.generateLink( type: GenerateLinkType.signup, email: '[email protected]', password: 'secret',);final actionLink = res.properties.actionLink;
Update a user
Parameters
- uidRequiredGenerateLinkType
User ID of the user to update.
- attributesRequiredAdminUserAttributes
Attributes to update for the user.
123456await supabase.auth.admin.updateUserById( '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4', attributes: AdminUserAttributes( email: '[email protected]', ),);
Invokes a Supabase Edge Function.
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
- functionNameRequiredString
The name of the function to invoke.
- headersOptionalMap<String, String>
Custom headers to send with the request.
- bodyOptionalMap<String, String>
The body of the request.
- methodOptionalHttpMethod
HTTP method of the request. Defaults to POST.
12final res = await supabase.functions.invoke('hello', body: {'foo': 'baa'});final data = res.data;
Listen to database changes
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 asStream<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.
- 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
12345supabase.from('countries') .stream(primaryKey: ['id']) .listen((List<Map<String, dynamic>> data) { // Do something awesome with the data});
Subscribe to channel
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
toFULL
, like this:ALTER TABLE your_table REPLICA IDENTITY FULL;
12345678910supabase .channel('public:countries') .onPostgresChanges( event: PostgresChangeEvent.all, schema: 'public', table: 'countries', callback: (payload) { print('Change received: ${payload.toString()}'); }) .subscribe();
Unsubscribe from a channel
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.
1final status = await supabase.removeChannel(channel);
Unsubscribe from all channels
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.
1final statuses = await supabase.removeAllChannels();
Retrieve all channels
Returns all Realtime channels.
1final channels = supabase.getChannels();
Create a bucket
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
- idRequiredString
A unique identifier for the bucket you are creating.
- bucketOptionsOptionalBucketOptions
A parameter to optionally make the bucket public.
123final String bucketId = await supabase .storage .createBucket('avatars');
Retrieve a bucket
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
- idRequiredString
The unique identifier of the bucket you would like to retrieve.
123final Bucket bucket = await supabase .storage .getBucket('avatars');
List all buckets
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
123final List<Bucket> buckets = await supabase .storage .listBuckets();
Update a bucket
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
- idRequiredString
A unique identifier for the bucket you are updating.
- bucketOptionsRequiredBucketOptions
A parameter to optionally make the bucket public.
123final String res = await supabase .storage .updateBucket('avatars', const BucketOptions(public: false));
Delete a bucket
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
anddelete
objects
permissions: none
- Refer to the Storage guide on how access control works
Parameters
- idRequiredString
A unique identifier for the bucket you are deleting.
123final String res = await supabase .storage .deleteBucket('avatars');
Empty a bucket
Removes all objects inside a single bucket.
- Policy permissions required:
buckets
permissions:select
objects
permissions:select
anddelete
- Refer to the Storage guide on how access control works
Parameters
- idRequiredString
A unique identifier for the bucket you are emptying.
123final String res = await supabase .storage .emptyBucket('avatars');
Upload a file
Uploads a file to an existing bucket.
- Policy permissions required:
buckets
permissions: noneobjects
permissions:insert
- Refer to the Storage guide on how access control works
Parameters
- pathRequiredString
The relative file path. Should be of the format folder/subfolder/filename.png. The bucket must already exist before attempting to update.
- fileRequiredFile or Uint8List
File object to be stored in the bucket.
- fileOptionsOptionalFileOptions
- retryAttemptsOptionalint
Sets the retryAttempts parameter set across the storage client. Defaults to 10.
- retryControllerOptionalStorageRetryController
Pass a RetryController instance and call
cancel()
to cancel the retry attempts.
123456final avatarFile = File('path/to/file');final String fullPath = await supabase.storage.from('avatars').upload( 'public/avatar1.png', avatarFile, fileOptions: const FileOptions(cacheControl: '3600', upsert: false), );
Download a file
Downloads a file.
- Policy permissions required:
buckets
permissions: noneobjects
permissions:select
- Refer to the Storage guide on how access control works
Parameters
- pathRequiredString
The full path and file name of the file to be downloaded. For example folder/image.png.
- transformOptionalTransformOptions
Transform the asset before serving it to the client.
1234final Uint8List file = await supabase .storage .from('avatars') .download('avatar1.png');
List all files in a bucket
Lists all the files within a bucket.
- Policy permissions required:
buckets
permissions: noneobjects
permissions:select
- Refer to the Storage guide on how access control works
Parameters
- pathRequiredString
The folder path.
- searchOptionsOptionalSearchOptions
Options for the search operations such as limit and offset.
1234final List<FileObject> objects = await supabase .storage .from('avatars') .list();
Replace an existing file
Replaces an existing file at the specified path with a new one.
- Policy permissions required:
buckets
permissions: noneobjects
permissions:update
andselect
- Refer to the Storage guide on how access control works
Parameters
- pathRequiredString
The relative file path. Should be of the format folder/subfolder/filename.png. The bucket must already exist before attempting to update.
- fileRequiredFile or Uint8List
File object to be stored in the bucket.
- fileOptionsOptionalFileOptions
- retryAttemptsOptionalint
Sets the retryAttempts parameter set across the storage client. Defaults to 10.
- retryControllerOptionalStorageRetryController
Pass a RetryController instance and call
cancel()
to cancel the retry attempts.
123456final avatarFile = File('path/to/local/file');final String path = await supabase.storage.from('avatars').update( 'public/avatar1.png', avatarFile, fileOptions: const FileOptions(cacheControl: '3600', upsert: false), );
Move an existing file
Moves an existing file, optionally renaming it at the same time.
- Policy permissions required:
buckets
permissions: noneobjects
permissions:update
andselect
- Refer to the Storage guide on how access control works
Parameters
- fromPathRequiredString
The original file path, including the current file name. For example folder/image.png.
- toPathRequiredString
The new file path, including the new file name. For example folder/image-new.png.
1234final String result = await supabase .storage .from('avatars') .move('public/avatar1.png', 'private/avatar2.png');
Delete files in a bucket
Deletes files within the same bucket
- Policy permissions required:
buckets
permissions: noneobjects
permissions:delete
andselect
- Refer to the Storage guide on how access control works
Parameters
- pathsRequiredList<String>
A list of files to delete, including the path and file name. For example ['folder/image.png'].
1234final List<FileObject> objects = await supabase .storage .from('avatars') .remove(['avatar1.png']);
Create a signed URL
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: noneobjects
permissions:select
- Refer to the Storage guide on how access control works
Parameters
- pathRequiredString
The file path, including the file name. For example folder/image.png.
- expiresInRequiredint
The number of seconds until the signed URL expires. For example, 60 for a URL which is valid for one minute.
- transformOptionalTransformOptions
Transform the asset before serving it to the client.
1234final String signedUrl = await supabase .storage .from('avatars') .createSignedUrl('avatar1.png', 60);
Retrieve public URL
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: noneobjects
permissions: none
- Refer to the Storage guide on how access control works
Parameters
- pathRequiredString
The path and name of the file to generate the public URL for. For example folder/image.png.
- transformOptionalTransformOptions
Transform the asset before serving it to the client.
1234final String publicUrl = supabase .storage .from('public-bucket') .getPublicUrl('avatar1.png');