Flutter客户端库
supabase_flutter在 GitHub 上查看本参考文档记录了 Supabase 的 Flutter 库 supabase-flutter 中可用的所有对象和方法。您可以使用 supabase-flutter 与您的 Postgres 数据库交互、监听数据库更改、调用 Deno Edge Functions、构建登录和用户管理功能以及管理大文件。
我们还为非 Flutter 项目提供了 supabase 包。
安装
从 pub.dev 安装#
您可以从 pub.dev 安装 Supabase 包。
1flutter pub add supabase_flutter初始化
您可以使用 `Supabase` 类的静态 `initialize()` 方法初始化 Supabase。
Supabase 客户端是您访问 Supabase 其他功能的入口,也是与 Supabase 生态系统中我们提供的一切进行交互的最简单方式。
参数
- url必需字符串
您在项目仪表板中创建新项目时提供的唯一 Supabase URL。
- anonKey必需字符串
您在项目仪表板中创建新项目时提供的唯一 Supabase Key。
- headers可选Map<String, String>
要传递给 Supabase 客户端的自定义标头。
- httpClient可选Client
Supabase 客户端要使用的自定义 http 客户端。
- authOptions可选FlutterAuthClientOptions
更改身份验证行为的选项。
- postgrestOptions可选PostgrestClientOptions
更改 Postgrest 行为的选项。
- realtimeClientOptions可选RealtimeClientOptions
更改 Realtime 行为的选项。
- storageOptions可选StorageClientOptions
更改 Storage 行为的选项。
1Future<void> main() async {2 await Supabase.initialize(3 url: 'https://xyzcompany.supabase.co',4 anonKey: 'publishable-or-anon-key',5 );67 runApp(MyApp());8}910// Get a reference your Supabase client11final supabase = Supabase.instance.client;升级指南
尽管 `supabase_flutter` v2 带来了一些突破性变更,但大部分公共 API 应该相同,只有一些细微的例外。我们在幕后进行了大量更新,使 SDK 对 Flutter 和 Dart 开发者来说工作更直观。
升级客户端库#
确保您在 `pubspec.yaml` 文件中使用 v2 客户端库。
1supabase_flutter: ^2.0.0(可选)向 `Supabase.initialize()` 传递自定义配置现在已组织到单独的对象中。
1await Supabase.initialize(2 url: supabaseUrl,3 anonKey: supabaseKey,4 authFlowType: AuthFlowType.pkce,5 storageRetryAttempts: 10,6 realtimeClientOptions: const RealtimeClientOptions(7 logLevel: RealtimeLogLevel.info,8 ),9);身份验证更新#
Provider 重命名为 OAuthProvider#
`Provider` 枚举已重命名为 `OAuthProvider`。以前,`Provider` 符号经常与 provider 包中的类冲突,开发者需要添加导入前缀以避免冲突。通过新的更新,开发者可以在同一个代码库中使用 Supabase 和 Provider,而无需任何导入前缀。
1await supabase.auth.signInWithOAuth(2 Provider.google,3);使用 Apple 登录方法已弃用#
我们已在 v2 中移除了 sign_in_with_apple 依赖项。这是因为并非所有开发者都需要使用 Apple 登录,我们希望减少库中的依赖项数量。
在 v2 中,如果您需要使用 Apple 登录,可以将其作为单独的依赖项导入 sign_in_with_apple。我们还添加了 `auth.generateRawNonce()` 方法,以便轻松生成安全的 nonce。
1await supabase.auth.signInWithApple();初始化不等待会话刷新#
在 v1 中,`Supabase.initialize()` 会在返回之前等待会话刷新。这会导致应用程序启动时间延迟,尤其是在网络环境不佳时。
在 v2 中,`Supabase.initialize()` 在从本地存储获取会话后立即返回,这使得应用程序启动更快。因此,不能保证应用程序启动时会话有效。
如果您需要确保会话有效,可以访问 `isExpired` getter 来检查会话是否有效。如果会话已过期,您可以监听 `onAuthStateChange` 事件并等待新的 `tokenRefreshed` 事件触发。
1// Session is valid, no check required2final session = supabase.auth.currentSession;移除 OAuth 登录的 Flutter Webview 依赖项#
在 v1 中,在 iOS 上,您可以将 `BuildContext` 传递给 `signInWithOAuth()` 方法,以在 Flutter Webview 中启动 OAuth 流程。
在 v2 中,我们已删除 webview_flutter 依赖项,以便您可以完全控制 OAuth 流程的 UI。我们现在 原生支持 Google 和 Apple 登录,因此在 iOS 上不再需要打开外部浏览器。
由于此更新,我们不再需要 `context` 参数,因此我们已从 `signInWithOAuth()` 方法中删除了 `context` 参数。
1// Opens a webview on iOS.2await supabase.auth.signInWithOAuth(3 Provider.github,4 authScreenLaunchMode: LaunchMode.inAppWebView,5 context: context,6);1await Supabase.initialize(2 url: 'SUPABASE_URL',3 anonKey: 'SUPABASE_ANON_KEY',4 authFlowType: AuthFlowType.implicit, // set to implicit by default5);身份验证回调主机名参数已移除#
`Supabase.initialize()` 不再具有 `authCallbackUrlHostname` 参数。`supabase_flutter` SDK 将自动检测身份验证回调 URL 并在内部处理它们。
1await Supabase.initialize(2 url: 'SUPABASE_URL',3 anonKey: 'SUPABASE_ANON_KEY',4 authCallbackUrlHostname: 'auth-callback',5);SupabaseAuth 类已移除#
`SupabaseAuth` 曾经有一个 `initialSession` 成员,用于在应用程序启动时获取初始会话。现在已移除此成员,应使用 `currentSession` 随时访问会话。
1// Use `initialSession` to obtain the initial session when the app starts.2final initialSession = await SupabaseAuth.initialSession;数据方法#
插入并返回数据#
我们使查询构建器不可变,这意味着您可以重用相同的查询对象来链式调用多个过滤器并获得预期的结果。
1// If you declare a query and chain filters on it2final myQuery = supabase.from('my_table').select();34final foo = await myQuery.eq('some_col', 'foo');56// The `eq` filter above is applied in addition to the following filter7final bar = await myQuery.eq('another_col', 'bar');重命名 is 和 in 过滤器#
由于 `is` 和 `in` 是 Dart 中的保留关键字,v1 使用 `is_` 和 `in_` 作为查询过滤器名称。用户发现下划线令人困惑,因此查询过滤器现在重命名为 `isFilter` 和 `inFilter`。
1final data = await supabase2 .from('users')3 .select()4 .is_('status', null);56final data = await supabase7 .from('users')8 .select()9 .in_('status', ['ONLINE', 'OFFLINE']);弃用 FetchOption,转而使用 `count()` 和 `head()` 方法#
`FetchOption()` 在 `.select()` 上现已弃用,并且新的 `.count()` 和 `head()` 方法已添加到查询构建器中。
`select()` 上的 `count()` 在执行选择的同时获取计数,而直接在 `from()` 上的 `count()` 执行 head 请求,仅获取计数。
1// Request with count option2final res = await supabase.from('cities').select(3 'name',4 const FetchOptions(5 count: CountOption.exact,6 ),7 );89final data = res.data;10final count = res.count;1112// Request with count and head option13// obtains the count value without fetching the data.14final res = await supabase.from('cities').select(15 'name',16 const FetchOptions(17 count: CountOption.exact,18 head: true,19 ),20 );2122final count = res.count;PostgREST 错误代码#
API 方法抛出的 `PostgrestException` 实例具有 `code` 属性。在 v1 中,`code` 属性包含 http 状态码。
在 v2 中,`code` 属性包含 PostgREST 错误代码,这对于调试更有用。
1try {2 await supabase.from('countries').select();3} on PostgrestException catch (error) {4 error.code; // Contains http status code5}实时方法#
实时方法包含最大的突破性变化。这些变化大部分是为了使接口更具类型安全性。
我们已移除 `.on()` 方法,并将其替换为 `.onPostgresChanges()`、`.onBroadcast()` 和三种不同的存在方法。
Postgres 更改#
使用新的 `.onPostgresChanges()` 方法监听数据库中的实时更改。
在 v1 中,过滤器不是强类型的,因为它们接受 `String` 类型。在 v2 中,`filter` 接受一个对象。其属性是严格类型化的,以捕获类型错误。
回调的有效载荷现在也已类型化。在 `v1` 中,有效载荷作为 `dynamic` 返回。现在它作为 `PostgresChangePayload` 对象返回。该对象包含 `oldRecord` 和 `newRecord` 属性,用于访问更改前后的数据。
1supabase.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();广播#
广播现在使用专用的 `.onBroadcast()` 方法,而不是通用的 `.on()` 方法。由于该方法特定于广播,因此它接受的属性较少。
1supabase.channel('my_channel').on(2 RealtimeListenTypes.broadcast,3 ChannelFilter(4 event: 'position',5 ),6 (dynamic payload, [ref]) {7 print(payload);8 },9).subscribe();存在#
实时存在获得三种不同的方法来监听三种不同的存在事件:`sync`、`join` 和 `leave`。这使得回调可以严格类型化。
1final channel = supabase.channel('room1');23channel.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);获取数据
对表或视图执行 SELECT 查询。
- 默认情况下,Supabase 项目将返回最多 1,000 行。 可以在项目 API 设置中更改此设置。 建议将其保持较低,以限制意外或恶意请求的有效负载大小。 您可以使用
range()查询来分页您的数据。 - `select()` 可以与过滤器结合使用。
- `select()` 可以与修改器结合使用。
apikey如果您使用 Supabase 平台 和 应该避免作为列名,则是一个保留关键字。
参数
- 列可选字符串
要检索的列,用逗号分隔。返回时可以使用 `customName:columnName` 重命名列。
1final data = await supabase2 .from('instruments')3 .select();插入数据
对表或视图执行 INSERT 操作。
参数
- 值必需Map<String, dynamic> 或 List<Map<String, dynamic>>
要插入的值。传递一个对象以插入单行,或传递一个数组以插入多行。
1await supabase2 .from('cities')3 .insert({'name': 'The Shire', 'country_id': 554});更新数据
执行 UPDATE 到表或视图。
- `update()` 应该始终与过滤器结合使用,以定位您希望更新的项。
参数
- 值必需Map<String, dynamic>
要更新的值。
1await supabase2 .from('instruments')3 .update({ 'name': 'piano' })4 .eq('id', 1);更新或插入数据
对表或视图执行 UPSERT 操作。根据传递给 `onConflict` 的列,如果具有相应 `onConflict` 列的行不存在,`.upsert()` 允许您执行相当于 `.insert()` 的操作;如果存在,则根据 `ignoreDuplicates` 执行替代操作。
- 要使用 upsert,必须在
values中包含主键。
参数
- 值必需Map<String, dynamic> 或 List<Map<String, dynamic>>
要 upsert 的值。传递一个 Map 以 upsert 单行,或传递一个数组以 upsert 多行。
- onConflict可选字符串
逗号分隔的 UNIQUE 列,用于指定如何确定重复行。如果所有 `onConflict` 列都相等,则两行是重复的。
- ignoreDuplicates可选bool
如果为 `true`,则忽略重复行。如果为 `false`,则将重复行与现有行合并。
- defaultToNull可选bool
使缺失字段默认为 `null`。否则,使用列的默认值。这仅适用于插入新行,而不适用于在 `ignoreDuplicates` 设置为 false 时与现有行合并。这也仅适用于批量 upsert。
1final data = await supabase2 .from('instruments')3 .upsert({ 'id': 1, 'name': 'piano' })4 .select();删除数据
执行 DELETE 到表或视图。
- `delete()` 应该始终与过滤器结合使用,以定位您希望删除的项。
- 如果您使用带有过滤器的 `delete()` 并且启用了 RLS,则只会删除通过 `SELECT` 策略可见的行。请注意,默认情况下没有行可见,因此您至少需要一个使行可见的 `SELECT` / `ALL` 策略。
1await supabase2 .from('countries')3 .delete()4 .eq('id', 1);调用 Postgres 函数
执行函数调用。
您可以将 Postgres 函数作为远程过程调用执行,这是您可以在任何地方执行的数据库逻辑。当逻辑很少更改时(例如密码重置和更新),函数会很有用。
参数
- fn必需字符串
要调用的函数名称。
- params可选Map<String, dynamic>
要传递给函数调用的参数。
1final data = await supabase2 .rpc('hello_world');使用过滤器
过滤器允许你仅返回匹配特定条件的行。
过滤器可用于 select()、update()、upsert() 和 delete() 查询。
如果数据库函数返回表响应,您还可以应用过滤器。
1final data = await supabase2 .from('cities')3 .select('name, country_id')4 .eq('name', 'The Shire'); // Correct56final data = await supabase7 .from('cities')8 .eq('name', 'The Shire') // Incorrect9 .select('name, country_id');列等于一个值
仅匹配 column 等于 value 的行。
参数
- column必需字符串
要过滤的列。
- value必需对象
用于过滤的值。
1final data = await supabase2 .from('instruments')3 .select()4 .eq('name', 'viola');列不等于一个值
查找所有 column 的值与指定的 value 不匹配的行。
参数
- column必需字符串
要过滤的列。
- value必需对象
用于过滤的值。
1final data = await supabase2 .from('instruments')3 .select('id, name')4 .neq('name', 'viola');列大于一个值
查找所有 column 的值大于指定的 value 的行。
参数
- column必需字符串
要过滤的列。
- value必需对象
用于过滤的值。
1final data = await supabase2 .from('countries')3 .select()4 .gt('id', 2);列大于或等于一个值
查找所有 column 的值大于或等于指定的 value 的行。
参数
- column必需字符串
要过滤的列。
- value必需对象
用于过滤的值。
1final data = await supabase2 .from('countries')3 .select()4 .gte('id', 2);列小于一个值
查找所有 column 的值小于指定的 value 的行。
参数
- column必需字符串
要过滤的列。
- value必需对象
用于过滤的值。
1final data = await supabase2 .from('countries')3 .select()4 .lt('id', 2);列小于或等于一个值
查找所有 column 的值小于或等于指定的 value 的行。
参数
- column必需字符串
要过滤的列。
- value必需对象
用于过滤的值。
1final data = await supabase2 .from('countries')3 .select()4 .lte('id', 2);列匹配一个模式
查找所有 column 的值与提供的 pattern 匹配的行(区分大小写)。
参数
- column必需字符串
要过滤的列。
- pattern必需字符串
要匹配的模式。
1final data = await supabase2 .from('planets')3 .select()4 .like('name', '%Ea%');列匹配一个不区分大小写的模式
查找所有 column 的值与提供的 pattern 匹配的行(不区分大小写)。
参数
- column必需字符串
要过滤的列。
- pattern必需字符串
要匹配的模式。
1final data = await supabase2 .from('planets')3 .select()4 .ilike('name', '%ea%');列是一个值
用于精确相等性(null、true、false)的检查,查找所有 column 的值与指定的 value 完全匹配的行。
参数
- column必需字符串
要过滤的列。
- value必需Object?
用于过滤的值。
1final data = await supabase2 .from('countries')3 .select()4 .isFilter('name', null);列在一个数组中
查找所有 column 的值在指定的 values 中找到的行。
参数
- column必需字符串
要过滤的列。
- 值必需List
用于过滤的 List。
1final data = await supabase2 .from('characters')3 .select()4 .inFilter('name', ['Luke', 'Leia']);列包含数组中的每个元素
仅适用于 jsonb、数组和范围列。仅匹配 column 包含 value 中出现的每个元素的行。
参数
- column必需字符串
要过滤的 jsonb、数组或范围列。
- value必需对象
要过滤的 jsonb、数组或范围值。
1final data = await supabase2 .from('issues')3 .select()4 .contains('tags', ['is:open', 'priority:low']);包含在值中
仅与 jsonb、数组和范围列相关。仅匹配 `column` 中出现的每个元素都包含在 `value` 中的行。
参数
- column必需字符串
要过滤的 jsonb、数组或范围列。
- value必需对象
要过滤的 jsonb、数组或范围值。
1final data = await supabase2 .from('classes')3 .select('name')4 .containedBy('days', ['monday', 'tuesday', 'wednesday', 'friday']);大于一个范围
仅与范围列相关。仅匹配 `column` 中的每个元素都大于 `range` 中任何元素的行。
参数
- column必需字符串
要过滤的范围列。
- range必需字符串
用于过滤的范围。
1final data = await supabase2 .from('reservations')3 .select()4 .rangeGt('during', '[2000-01-02 08:00, 2000-01-02 09:00)');大于或等于一个范围
仅与范围列相关。仅匹配 `column` 中的每个元素都包含在 `range` 中或大于 `range` 中任何元素的行。
参数
- column必需字符串
要过滤的范围列。
- range必需字符串
用于过滤的范围。
1final data = await supabase2 .from('reservations')3 .select()4 .rangeGte('during', '[2000-01-02 08:30, 2000-01-02 09:30)');小于一个范围
仅与范围列相关。仅匹配 `column` 中的每个元素都小于 `range` 中任何元素的行。
参数
- column必需字符串
要过滤的范围列。
- range必需字符串
用于过滤的范围。
1final data = await supabase2 .from('reservations')3 .select()4 .rangeLt('during', '[2000-01-01 15:00, 2000-01-01 16:00)');小于或等于一个范围
仅与范围列相关。仅匹配 `column` 中的每个元素都包含在 `range` 中或小于 `range` 中任何元素的行。
参数
- column必需字符串
要过滤的范围列。
- range必需字符串
用于过滤的范围。
1final data = await supabase2 .from('reservations')3 .select()4 .rangeLte('during', '[2000-01-01 15:00, 2000-01-01 16:00)');与范围互斥
仅与范围列相关。仅匹配 `column` 与 `range` 互斥且两个范围之间不能有任何元素的行。
参数
- column必需字符串
要过滤的范围列。
- range必需字符串
用于过滤的范围。
1final data = await supabase2 .from('reservations')3 .select()4 .rangeAdjacent('during', '[2000-01-01 12:00, 2000-01-01 13:00)');具有共同元素
仅与数组和范围列相关。仅匹配 `column` 和 `value` 有共同元素的行。
参数
- column必需字符串
要过滤的数组或范围列。
- value必需对象
要过滤的数组或范围值。
1final data = await supabase2 .from('issues')3 .select('title')4 .overlaps('tags', ['is:closed', 'severity:high']);匹配一个字符串
查找所有 `column` 的 tsvector 值与 to_tsquery(query) 匹配的行。
参数
- column必需字符串
要过滤的文本或 tsvector 列。
- query必需字符串
要匹配的查询文本。
- config可选字符串
要使用的文本搜索配置。
- type可选TextSearchType
更改 `query` 文本的解释方式。
1final data = await supabase2 .from('quotes')3 .select('catchphrase')4 .textSearch('content', "'eggs' & 'ham'",5 config: 'english'6 );匹配关联值
查找所有列与指定 `query` 对象匹配的行。
参数
- query必需Map<String, dynamic>
用于过滤的对象,其中列名作为键映射到其过滤值。
1final data = await supabase2 .from('instruments')3 .select()4 .match({ 'id': 2, 'name': 'viola' });不匹配过滤器
查找所有不满足过滤条件的行。
-
`.not()` 期望您使用原始的 PostgREST 语法 进行过滤器名称和值。
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.
参数
- column必需字符串
要过滤的列。
- operator必需字符串
要取反的运算符以进行过滤,遵循 PostgREST 语法。
- value可选对象
用于过滤的值,遵循 PostgREST 语法。
1final data = await supabase2 .from('countries')3 .select()4 .not('name', 'is', null)匹配至少一个过滤器
查找满足至少一个过滤器的所有行。
-
`.or()` 期望您使用原始的 PostgREST 语法 进行过滤器名称和值。
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.
参数
- filters必需字符串
要使用的过滤器,遵循 PostgREST 语法
- referencedTable可选字符串
将其设置为过滤引用表而不是父表。
1final data = await supabase2 .from('instruments')3 .select('name')4 .or('id.eq.2,name.eq.cello');匹配过滤器
仅匹配满足过滤条件的行。这是一个逃生舱口——您应该尽可能使用特定的过滤方法。
`.filter()` 期望您使用原始的 PostgREST 语法 进行过滤器名称和值,因此它只应在其他过滤器不起作用时作为逃生舱口使用。
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.参数
- column必需字符串
要过滤的列。
- operator必需字符串
用于过滤的运算符,遵循 PostgREST 语法。
- value必需对象
用于过滤的值,遵循 PostgREST 语法。
1final data = await supabase2 .from('characters')3 .select()4 .filter('name', 'in', '("Ron","Dumbledore")')使用修饰符
过滤器在行级别工作。也就是说,它们允许您返回只匹配某些条件的行,而无需更改行的形状。修改器是所有不符合该定义的内容——允许您更改响应的格式(例如,返回 CSV 字符串)。
修饰符必须在过滤器之后指定。某些修饰符仅适用于返回行的查询(例如,select() 或返回表响应的函数的 rpc())。
插入后返回数据
1final data = await supabase2 .from('instruments')3 .upsert({ 'id': 1, 'name': 'piano' })4 .select();对结果进行排序
使用指定列对结果进行排序。
参数
- column必需字符串
要排序的列。
- ascending可选bool
是否按升序排序。默认为 `false`。
- nullsFirst可选bool
是否将 null 排在前面。默认为 `false`。
- referencedTable可选字符串
在按嵌入资源中的列排序时指定引用表。
1final data = await supabase2 .from('instruments')3 .select('id, name')4 .order('id', ascending: false);限制返回的行数
根据指定计数限制结果。
参数
- count必需int
要返回的最大行数。
- referencedTable可选int
将其设置为限制引用表的行而不是父表。
1final data = await supabase2 .from('instruments')3 .select('name')4 .limit(1);将查询限制在一个范围内
将结果限制在指定范围内的行(包括端点)。
参数
- from必需int
限制结果的起始索引。
- to必需int
限制结果的最后一个索引。
- referencedTable可选字符串
将其设置为限制引用表的行而不是父表。
1final data = await supabase2 .from('instruments')3 .select('name')4 .range(0, 1);检索一行数据
仅从结果中检索一行。结果必须是一行(例如使用 limit),否则将导致错误。
1final data = await supabase2 .from('instruments')3 .select('name')4 .limit(1)5 .single();检索零行或一行数据
1final data = await supabase2 .from('instruments')3 .select()4 .eq('name', 'guzheng')5 .maybeSingle();检索为 CSV
1final data = await supabase2 .from('instruments')3 .select()4 .csv();使用 explain
为了调试慢查询,你可以使用 explain() 方法获取查询的 Postgres EXPLAIN 执行计划。这适用于任何查询,甚至适用于 rpc() 或写入。
Explain 默认情况下未启用,因为它可能会泄露数据库中的敏感信息。最好仅在测试环境中使用,但如果您希望在生产环境中使用,可以通过使用 `pre-request` 函数提供额外的保护。
请遵循 性能调试指南 以在您的项目上启用此功能。
参数
- analyze可选bool
如果为 `true`,则将执行查询并返回实际运行时间。
- verbose可选bool
如果为 `true`,则将返回查询标识符,并且 `data` 将包含查询的输出列。
- settings可选bool
如果为 `true`,则包含影响查询计划的配置参数信息。
- buffers可选bool
如果为 `true`,则包含缓冲区使用情况信息。
- wal可选bool
如果为 `true`,则包含 WAL 记录生成信息。
1final data = await supabase2 .from('instruments')3 .select()4 .explain();创建新用户
创建一个新用户。
- 默认情况下,用户需要在登录前验证其电子邮件地址。要关闭此功能,请在 您的项目 中禁用 **确认电子邮件**。
- **确认电子邮件** 确定用户在注册后是否需要确认其电子邮件地址。
- 如果启用了 **确认电子邮件**,则会返回一个 `user`,但 `session` 为 null。
- 如果禁用了 **确认电子邮件**,则会同时返回 `user` 和 `session`。
- 当用户确认其电子邮件地址时,他们默认会重定向到 `SITE_URL`。您可以在您的项目中修改 `SITE_URL` 或添加额外的重定向 URL。
- 如果对已存在的已确认用户调用 signUp()
- 当在 您的项目 中同时启用 **确认电子邮件** 和 **确认电话**(即使电话提供程序已禁用)时,将返回一个混淆/虚假的用户对象。
- 当 **确认电子邮件** 或 **确认电话**(即使电话提供程序已禁用)中的任何一个被禁用时,将返回错误消息 `User already registered`。
参数
- email可选字符串
用于电子邮件身份验证的用户电子邮件地址。
- phone可选字符串
用于电话身份验证的用户电话号码。
- password必需字符串
用于身份验证的密码。
- emailRedirectTo可选字符串
用户确认电子邮件地址后重定向到的 URL。
- data可选Map<String, dynamic>
要存储在用户对象中的用户元数据。
- captchaToken可选字符串
用于验证码验证的验证码令牌。
- channel可选OtpChannel
要使用的消息通道(例如 whatsapp 或 sms)。默认为 `OtpChannel.sms`。
1final AuthResponse res = await supabase.auth.signUp(2 email: 'example@email.com',3 password: 'example-password',4);5final Session? session = res.session;6final User? user = res.user;监听认证事件
每次发生身份验证事件时接收通知。
- 身份验证事件类型:`AuthChangeEvent.passwordRecovery`、`AuthChangeEvent.signedIn`、`AuthChangeEvent.signedOut`、`AuthChangeEvent.tokenRefreshed`、`AuthChangeEvent.userUpdated` 和 `AuthChangeEvent.userDeleted`
1final authSubscription = supabase.auth.onAuthStateChange.listen((data) {2 final AuthChangeEvent event = data.event;3 final Session? session = data.session;45 print('event: $event, session: $session');67 switch (event) {8 case AuthChangeEvent.initialSession:9 // handle initial session10 case AuthChangeEvent.signedIn:11 // handle signed in12 case AuthChangeEvent.signedOut:13 // handle signed out14 case AuthChangeEvent.passwordRecovery:15 // handle password recovery16 case AuthChangeEvent.tokenRefreshed:17 // handle token refreshed18 case AuthChangeEvent.userUpdated:19 // handle user updated20 case AuthChangeEvent.userDeleted:21 // handle user deleted22 case AuthChangeEvent.mfaChallengeVerified:23 // handle mfa challenge verified24 }25});创建匿名用户
创建匿名用户。
- 返回一个匿名用户
- 建议为匿名注册设置验证码以防止滥用。您可以在 `options` 参数中传递验证码令牌。
参数
- data可选Map<String, dynamic>
要存储在用户对象中的用户元数据。
- captchaToken可选字符串
用于验证码验证的验证码令牌。
1await supabase.auth.signInAnonymously();登录用户
使用电子邮件或电话号码和密码登录现有用户。
- 需要电子邮件和密码或电话号码和密码。
参数
- email可选字符串
用于电子邮件身份验证的用户电子邮件地址。
- phone可选字符串
用于电话身份验证的用户电话号码。
- password必需字符串
用于身份验证的密码。
- captchaToken可选字符串
用于验证码验证的验证码令牌。
1final AuthResponse res = await supabase.auth.signInWithPassword(2 email: 'example@email.com',3 password: 'example-password',4);5final Session? session = res.session;6final User? user = res.user;使用 ID Token 登录 (原生登录)
允许您通过与 google_sign_in、sign_in_with_apple 或 flutter_facebook_auth 包结合使用,执行原生 Google、Apple 和 Facebook 登录。
参数
- provider必需OAuthProvider
用于执行登录的提供商。
- idToken必需字符串
从第三方提供商获得的身份令牌。
- accessToken可选字符串
从第三方提供商获得的访问令牌。Google 登录必需。
- nonce可选字符串
用于执行第三方登录的原始 nonce 值。Apple 登录必需。
- captchaToken可选字符串
用于验证码验证的验证码令牌。
1import 'package:google_sign_in/google_sign_in.dart';2import 'package:supabase_flutter/supabase_flutter.dart';34const webClientId = '<web client ID that you registered on Google Cloud, for example my-web.apps.googleusercontent.com>';56const iosClientId = '<iOS client ID that you registered on Google Cloud, for example my-ios.apps.googleusercontent.com';78final GoogleSignIn googleSignIn = GoogleSignIn(9 clientId: iosClientId,10 serverClientId: webClientId,11);12final googleUser = await googleSignIn.signIn();13final googleAuth = await googleUser!.authentication;14final accessToken = googleAuth.accessToken;15final idToken = googleAuth.idToken;1617if (accessToken == null) {18 throw 'No Access Token found.';19}20if (idToken == null) {21 throw 'No ID Token found.';22}2324final response = await supabase.auth.signInWithIdToken(25 provider: OAuthProvider.google,26 idToken: idToken,27 accessToken: accessToken,28);通过 OTP 登录用户
- 需要电子邮件或电话号码。
- 此方法用于无密码登录,其中 OTP 会发送到用户的电子邮件或电话号码。
- 如果您使用的是电子邮件,可以配置是希望用户接收魔术链接还是 OTP。
- 如果您使用的是电话,可以配置是希望用户接收 OTP。
- 魔术链接的目标 URL 由 `SITE_URL` 决定。您可以在您的项目中修改 `SITE_URL` 或添加额外的重定向 URL。
参数
- email可选字符串
发送魔术链接或 OTP 的电子邮件地址。
- phone可选字符串
发送 OTP 的电话号码。
- emailRedirectTo可选字符串
用户点击魔术链接后重定向到的 URL。
- shouldCreateUser可选bool
如果设置为 false,此方法将不会创建新用户。默认为 true。
- data可选Map<String, dynamic>
要存储在用户对象中的用户元数据。
- captchaToken可选字符串
用于验证码验证的验证码令牌。
- channel可选OtpChannel
要使用的消息通道(例如 whatsapp 或 sms)。默认为 `OtpChannel.sms`。
1await supabase.auth.signInWithOtp(2 email: 'example@email.com',3 emailRedirectTo: kIsWeb ? null : 'io.supabase.flutter://signin-callback/',4);通过 OAuth 登录用户
使用第三方 OAuth 提供商登录用户。
- 此方法用于使用第三方提供程序登录。
- Supabase 支持许多不同的 第三方提供程序。
参数
- provider必需OAuthProvider
用于登录的 OAuth 提供商。
- redirectTo可选字符串
用户使用第三方提供商登录后重定向到的 URL。
- scopes可选字符串
要从第三方提供商请求的范围列表。
- authScreenLaunchMode可选LaunchMode
身份验证屏幕的启动模式。默认为 `LaunchMode.platformDefault`。
- queryParams可选Map<String, String>
要传递给 OAuth 流的额外查询参数。
1await 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);通过 SSO 登录用户
- 在您可以使用此方法之前,您需要 建立与身份提供程序的连接。使用 CLI 命令 来执行此操作。
- 如果您已将电子邮件域与身份提供程序关联,则可以使用 `domain` 属性启动登录流程。
- 如果您需要使用不同的方式使用身份提供程序启动身份验证流程,可以使用 `providerId` 属性。例如
- 将特定的用户电子邮件地址与身份提供程序映射。
- 使用不同的提示来识别正确的身份提供商,例如公司特定页面、IP 地址或其他跟踪信息。
参数
- providerId可选字符串
用于登录的 SSO 提供商的 ID。
- domain可选字符串
用于登录的电子邮件域。
- redirectTo可选字符串
用户使用第三方提供商登录后重定向到的 URL。
- captchaToken可选字符串
用于验证码验证的验证码令牌。
- launchMode可选LaunchMode
身份验证屏幕的启动模式。默认为 `LaunchMode.platformDefault`。
1await supabase.auth.signInWithSSO(2 domain: 'company.com',3);注销用户
如果有已登录用户,则登出当前用户。
- 为了使用 `signOut()` 方法,用户需要先登录。
参数
- scope可选SignOutScope
是登出所有设备还是仅登出当前设备。默认为 `SignOutScope.local`。
1await supabase.auth.signOut();通过 OTP 验证并登录
- `verifyOtp` 方法接受不同的验证类型。如果使用电话号码,类型可以是 `sms` 或 `phone_change`。如果使用电子邮件地址,类型可以是以下之一:`email`、`recovery`、`invite` 或 `email_change`(`signup` 和 `magiclink` 类型已弃用)。
- 所使用的验证类型应根据之前为注册或登录用户而调用的相应身份验证方法确定。
参数
- token必需字符串
发送给用户电子邮件或手机的令牌
- type必需OtpType
要验证的 OTP 类型
- email可选字符串
发送 OTP 的电子邮件地址
- phone可选字符串
发送 OTP 的电话号码
- redirectTo可选字符串
OTP 验证后重定向用户的 URI
- captchaToken可选字符串
用于验证码验证的验证码令牌
- tokenHash可选字符串
电子邮件链接中使用的令牌
1final AuthResponse res = await supabase.auth.verifyOTP(2 type: OtpType.signup,3 token: token,4 phone: '+13334445555',5);6final Session? session = res.session;7final User? user = res.user;获取会话
如果存在活动会话,则返回会话数据。
1final Session? session = supabase.auth.currentSession;获取新的会话
- 此方法将刷新并返回新会话,无论当前会话是否过期。
1final AuthResponse res = await supabase.auth.refreshSession();2final session = res.session;获取用户
如果有已登录用户,则返回用户数据。
1final User? user = supabase.auth.currentUser;更新用户
更新已登录用户的用户数据。
- 为了使用 `updateUser()` 方法,用户需要先登录。
- 默认情况下,电子邮件更新会将确认链接发送到用户的当前电子邮件和新电子邮件。要仅将确认链接发送到用户的新的电子邮件,请在您项目的 电子邮件身份验证提供程序设置 中禁用 **安全电子邮件更改**。
参数
- attributes必需UserAttributes
要为用户更新的属性。
- emailRedirectTo可选字符串
电子邮件更新后重定向用户的 URI。
1final UserResponse res = await supabase.auth.updateUser(2 UserAttributes(3 email: 'example@email.com',4 ),5);6final User? updatedUser = res.user;获取与用户关联的身份
获取链接到用户的所有身份。
- 用户需要登录才能调用 `getUserIdentities()`。
1final identities = await supabase.auth.getUserIdentities();将身份与用户关联
将 OAuth 身份链接到现有用户。此方法支持 PKCE 流程。
- 必须从您的 项目身份验证设置 中启用 **启用手动链接** 选项。
- 需要先登录才能调用 `linkIdentity()`。
- 如果候选身份已链接到现有用户或另一个用户,`linkIdentity()` 将失败。
参数
- provider必需OAuthProvider
要将身份链接到的提供商。
- redirectTo可选字符串
用户使用第三方提供商登录后重定向到的 URL。
- scopes可选字符串
要从第三方提供商请求的范围列表。
- authScreenLaunchMode可选LaunchMode
身份验证屏幕的启动模式。默认为 `LaunchMode.platformDefault`。
- queryParams可选Map<String, String>
要传递给 OAuth 流的额外查询参数。
1await supabase.auth.linkIdentity(OAuthProvider.google);将身份从用户取消关联
通过删除身份来取消身份与用户的关联。用户一旦取消关联,将无法再使用该身份登录。
- 必须从您的 项目身份验证设置 中启用 **启用手动链接** 选项。
- 用户需要已登录才能调用
unlinkIdentity()。 - 用户必须至少拥有 2 个身份才能取消关联一个身份。
- 要取消关联的身份必须属于该用户。
参数
- identity必需UserIdentity
要取消关联的用户身份。
1// retrieve all identities linked to a user2final identities = await supabase.auth.getUserIdentities();34// find the google identity5final googleIdentity = identities.firstWhere(6 (element) => element.provider == 'google',7);89// unlink the google identity10await supabase.auth.unlinkIdentity(googleIdentity);发送密码重新认证 nonce
- 当需要更新用户的密码时,此方法与
updateUser()结合使用。 - 此方法向用户的电子邮件发送一个 nonce。如果用户没有确认的电子邮件地址,则该方法将 nonce 发送给用户确认的电话号码。
1await supabase.auth.reauthenticate();重新发送 OTP
- 向用户重新发送注册确认、电子邮件更改或电话更改电子邮件。
- 可以通过再次调用 `signInWithOtp()` 方法来重新发送无密码登录。
- 可以通过再次调用
resetPasswordForEmail()方法重新发送密码恢复电子邮件。 - 此方法仅在发出初始注册、电子邮件更改或电话更改请求时向用户重新发送电子邮件或电话 OTP。
1final ResendResponse res = await supabase.auth.resend(2 type: OtpType.signup,3 email: 'email@example.com',4);设置会话数据
- `setSession()` 接受一个刷新令牌并使用它来获取一个新会话。
- 刷新令牌只能使用一次以获取新会话。
- 刷新令牌轮换默认在所有项目上启用,以防止重放攻击。
- 您可以配置 `REFRESH_TOKEN_REUSE_INTERVAL`,它提供了一个短窗口,在该窗口中,在并发或离线问题的情况下,可以多次使用相同的刷新令牌。
参数
- refreshToken必需字符串
用于获取新会话的刷新令牌。
1final refreshToken = supabase.currentSession?.refreshToken ?? '';2final AuthResponse response = await supabase.auth.setSession(refreshToken);34final session = res.session;认证 MFA
本节包含通常用于多因素身份验证 (MFA) 的方法,并在 supabase.auth.mfa 命名空间下调用。
目前,Supabase 支持基于时间的一次性密码 (TOTP) 和电话验证码作为第二因子。不支持恢复码,但用户可以注册多个因子,上限为 10 个。
拥有用于恢复的第二因子使用户免于存储恢复码的负担。它还减少了攻击面,因为通常会生成多个恢复码,而不是只有一个备份因子。
有关如何在应用程序上实施 MFA 的更多信息,请参阅我们的指南此处。
注册因素
开始新多因素身份验证(MFA)因子的注册过程。此方法创建一个新的 `unverified` 因子。要验证因子,请向用户出示二维码或密钥,并要求他们将其添加到其身份验证器应用。用户必须输入其身份验证器应用中的代码才能验证它。
- 使用 `totp` 或 `phone` 作为 `factorType` 和返回的 `id` 来创建挑战。
- 要创建挑战,请参阅`mfa.challenge()`。
- 要验证挑战,请参阅`mfa.verify()`。
- 要在单个步骤中创建和验证挑战,请参阅`mfa.challengeAndVerify()`。
参数
- factorType可选字符串
注册因子的类型。
- issuer可选字符串
用户注册的域。
- friendlyName可选字符串
分配给因子的人性化名称。
- phone可选字符串
用于电话因子类型的电话号码。
1final res = await supabase.auth.mfa.enroll(factorType: FactorType.totp);23final qrCodeUrl = res.totp.qrCode;创建挑战
准备用于验证用户是否可以访问 MFA 因子的挑战。
- 在创建挑战之前,需要一个已注册的因子。
- 要验证挑战,请参阅`mfa.verify()`。
参数
- factorId必需字符串
enroll 返回的身份验证器设备的系统分配标识符。
1final res = await supabase.auth.mfa.challenge(2 factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225',3);验证挑战
验证挑战的代码。验证码由用户通过在身份验证器应用中输入所看到的代码提供。
- 要验证挑战,请先创建挑战。
参数
- factorId必需字符串
enroll 返回的身份验证器设备的系统分配标识符。
- challengeId必需字符串
要验证的挑战的 ID
- code必需字符串
用户身份验证器应用上的验证码
1final res = await supabase.auth.mfa.verify(2 factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225',3 challengeId: '4034ae6f-a8ce-4fb5-8ee5-69a5863a7c15',4 code: '123456',5);创建并验证挑战
辅助方法,它创建一个挑战并随后立即使用给定的代码进行验证。验证码由用户通过在身份验证器应用中输入所看到的代码提供。
- 在调用 `challengeAndVerify()` 之前,需要一个已注册的因子。
- 在一个步骤中执行`mfa.challenge()` 和`mfa.verify()`。
参数
- factorId必需字符串
enroll 返回的身份验证器设备的系统分配标识符。
- code必需字符串
用户身份验证器应用上的验证码
1final res = await supabase.auth.mfa.challengeAndVerify(2 factorId: '34e770dd-9ff9-416c-87fa-43b31d7ef225',3 code: '123456',4);取消注册因素
取消注册将删除 MFA 因子。用户必须具有 `aal2` 身份验证级别才能取消注册 `verified` 因子。
参数
- factorId必需字符串
enroll 返回的身份验证器设备的系统分配标识符。
1final res = await supabase.auth.mfa.unenroll(2 '34e770dd-9ff9-416c-87fa-43b31d7ef225',3);获取身份验证器保证级别
返回活动会话的身份验证保障级别(AAL)。
- 身份验证器保证级别 (AAL) 是身份验证机制强度的度量。
- 在 Supabase 中,AAL 为 `aal1` 意味着用户已通过其第一因子登录,例如电子邮件、密码或 OAuth 登录。AAL 为 `aal2` 意味着用户也已通过其第二因子登录,例如基于时间的一次性密码 (TOTP)。
- 如果用户有一个已验证的因子,则 `nextLevel` 字段返回 `aal2`。否则,它返回 `aal1`。
1final res = supabase.auth.mfa.getAuthenticatorAssuranceLevel();2final currentLevel = res.currentLevel;3final nextLevel = res.nextLevel;4final currentAuthenticationMethods = res.currentAuthenticationMethods;认证 Admin
supabase.auth.admin命名空间下的任何方法都需要一个service_role密钥。- 这些方法被视为管理方法,应在受信任的服务器上调用。切勿在 Flutter 应用程序中公开您的 `service_role` 密钥。
1final supabase = SupabaseClient(supabaseUrl, serviceRoleKey);获取用户
通过 ID 获取用户。
- 根据用户的 ID 从数据库中获取用户对象。
- `getUserById()` 方法需要用户的 ID,该 ID 映射到 `auth.users.id` 列。
参数
- uid必需字符串
要获取的用户 ID。
1final res = await supabase.auth.admin.getUserById(userId);2final user = res.user;列出所有用户
获取用户列表。
- 默认情况下,每页返回 50 个用户。
参数
- page可选int
要返回的用户页码。
- page可选int
每页要返回的用户数量。默认为 50。
1// Returns the first 50 users.2final List<User> users = await supabase.auth.admin.listUsers();创建用户
创建一个新用户。
- 要确认用户的电子邮件地址或电话号码,请将
email_confirm或phone_confirm设置为 true。两个参数都默认为 false。 - `createUser()` 不会向用户发送确认电子邮件。如果您想向他们发送电子邮件邀请,可以使用`inviteUserByEmail()`。
- 如果您确定创建用户的电子邮件或电话号码是合法的且经过验证的,则可以将
email_confirm或phone_confirm参数设置为true。
参数
- attributes必需AdminUserAttributes
用于创建用户的属性。
1final res = await supabase.auth.admin.createUser(AdminUserAttributes(2 email: 'user@email.com',3 password: 'password',4 userMetadata: {'name': 'Yoda'},5));删除用户
删除用户。
deleteUser()方法需要用户的 ID,它映射到auth.users.id列。
参数
- id必需字符串
要删除的用户 ID。
1await supabase.auth.admin2 .deleteUser('715ed5db-f090-4b8c-a067-640ecee36aa0');发送电子邮件邀请链接
向用户的电子邮件地址发送邀请链接。
参数
- email必需字符串
要邀请的用户的电子邮件地址。
- redirectTo可选字符串
用户打开邀请链接后重定向到的 URI。
- data可选Map<String, dynamic>
用于存储用户元数据的自定义数据对象。这映射到 `auth.users.user_metadata` 列。
1final UserResponse res = await supabase.auth.admin2 .inviteUserByEmail('email@example.com');3final User? user = res.user;生成电子邮件链接
生成电子邮件链接和 OTP。这不会向最终用户发送链接或 OTP。此函数用于自定义管理功能。
- 以下类型可以传递给 `generateLink()`:`signup`、`magiclink`、`invite`、`recovery`、`emailChangeCurrent`、`emailChangeNew`、`phoneChange`。
- 仅当在 Supabase 项目的“电子邮件”提供商下启用了“安全电子邮件更改”设置时,`generateLink()` 才会为 `email_change_email` 生成电子邮件链接。
- `generateLink()` 处理 `signup`、`invite` 和 `magiclink` 用户的创建。
参数
- type必需GenerateLinkType
要生成的邀请链接类型。
- email必需字符串
要邀请的用户的电子邮件地址。
- password可选字符串
用户密码。`signup` 类型必需。
- redirectTo可选字符串
用户打开邀请链接后重定向到的 URI。
- data可选Map<String, dynamic>
用于存储用户元数据的自定义数据对象。这映射到 `auth.users.user_metadata` 列。
1final res = await supabase.auth.admin.generateLink(2 type: GenerateLinkType.signup,3 email: 'email@example.com',4 password: 'secret',5);6final actionLink = res.properties.actionLink;更新用户
参数
- uid必需GenerateLinkType
要更新的用户 ID。
- attributes必需AdminUserAttributes
要为用户更新的属性。
1await supabase.auth.admin.updateUserById(2 '6aa5d0d4-2a9f-4483-b6c8-0cf4c6c98ac4',3 attributes: AdminUserAttributes(4 email: 'new@email.com',5 ),6);调用 Supabase 边缘函数。
参数
- functionName必需字符串
要调用的函数名称。
- headers可选Map<String, String>
要随请求发送的自定义标头。
- body可选Map<String, String>
请求正文。
- method可选HttpMethod
请求的 HTTP 方法。默认为 POST。
1final res = await supabase.functions.invoke('hello', body: {'foo': 'baa'});2final data = res.data;监听数据库变化
以 `Stream` 形式从表中返回实时数据。
- 新表的实时功能默认禁用。您可以通过管理复制来启用它。
- `stream()` 将结合 Postgrest 和 Realtime 发出初始数据以及数据库中的任何进一步更改,作为 `Stream<List<Map<String, dynamic>>>`。
- 接受一个主键列名列表,这些列名将用于在 SDK 中更新和删除适当的记录。
- 提供以下过滤器
- `.eq('column', value)` 监听列等于值的行
- `.neq('column', value)` 监听列不等于值的行
- `.gt('column', value)` 监听列大于值的行
- `.gte('column', value)` 监听列大于或等于值的行
- `.lt('column', value)` 监听列小于值的行
- `.lte('column', value)` 监听列小于或等于值的行
- `.inFilter('column', [val1, val2, val3])` 监听列是其中一个值的行
1supabase.from('countries')2 .stream(primaryKey: ['id'])3 .listen((List<Map<String, dynamic>> data) {4 // Do something awesome with the data5});订阅频道
订阅数据库中的实时更改。
- 新表的实时功能默认禁用。您可以通过管理复制来启用它。
- 如果您想接收更新和删除的“先前”数据,则需要将
REPLICA IDENTITY设置为FULL,如下所示:ALTER TABLE your_table REPLICA IDENTITY FULL;
1supabase2 .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();取消订阅频道
取消订阅并从实时客户端中删除实时通道。
- 删除频道是维护项目实时服务性能以及数据库性能的好方法(如果你正在侦听 Postgres 更改)。Supabase 会在客户端断开连接 30 秒后自动处理清理,但未使用的频道可能会导致更多客户端同时订阅而导致性能下降。
1final status = await supabase.removeChannel(channel);取消订阅所有频道
取消订阅并从实时客户端删除所有实时通道。
- 删除频道是维护项目实时服务性能以及数据库性能的好方法(如果你正在侦听 Postgres 更改)。Supabase 会在客户端断开连接 30 秒后自动处理清理,但未使用的频道可能会导致更多客户端同时订阅而导致性能下降。
1final statuses = await supabase.removeAllChannels();获取所有频道
返回所有实时通道。
1final channels = supabase.getChannels();文件存储
本节包含处理文件存储桶的方法。
列出所有存储桶
检索现有产品中所有存储桶的详细信息。
- 所需策略权限
- `buckets` 权限:`select`
- `objects` 权限:无
- 请参阅存储指南了解访问控制的工作原理。
1final List<Bucket> buckets = await supabase2 .storage3 .listBuckets();检索存储桶
检索现有的存储存储桶的详细信息。
- 所需策略权限
- `buckets` 权限:`select`
- `objects` 权限:无
- 请参阅存储指南了解访问控制的工作原理。
参数
- id必需字符串
你要检索的存储桶的唯一标识符。
1final Bucket bucket = await supabase2 .storage3 .getBucket('avatars');创建存储桶
创建一个新的存储存储桶
- 所需策略权限
- `buckets` 权限:`insert`
- `objects` 权限:无
- 请参阅存储指南了解访问控制的工作原理。
参数
- id必需字符串
你要创建的存储桶的唯一标识符。
- bucketOptions可选BucketOptions
一个可选参数,用于使存储桶公开。
1final String bucketId = await supabase2 .storage3 .createBucket('avatars');清空存储桶
删除单个存储桶中的所有对象。
- 所需策略权限
- `buckets` 权限:`select`
- `objects` 权限:`select` 和 `delete`
- 请参阅存储指南了解访问控制的工作原理。
参数
- id必需字符串
要清空存储桶的唯一标识符。
1final String res = await supabase2 .storage3 .emptyBucket('avatars');更新存储桶
更新新的存储桶
- 所需策略权限
- `buckets` 权限:`update`
- `objects` 权限:无
- 请参阅存储指南了解访问控制的工作原理。
参数
- id必需字符串
要更新存储桶的唯一标识符。
- bucketOptions必需BucketOptions
一个可选参数,用于使存储桶公开。
1final String res = await supabase2 .storage3 .updateBucket('avatars', const BucketOptions(public: false));删除存储桶
删除现有的存储桶。如果存储桶内存在现有对象,则无法删除存储桶。你必须首先 empty() 存储桶。
- 所需策略权限
- `buckets` 权限:`select` 和 `delete`
- `objects` 权限:无
- 请参阅存储指南了解访问控制的工作原理。
参数
- id必需字符串
要删除存储桶的唯一标识符。
1final String res = await supabase2 .storage3 .deleteBucket('avatars');上传文件
将文件上传到现有的存储桶。
- 所需策略权限
- `buckets` 权限:无
- `objects` 权限:`insert`
- 请参阅存储指南了解访问控制的工作原理。
参数
- path必需字符串
相对文件路径。应采用 folder/subfolder/filename.png 格式。存储桶必须在尝试更新之前存在。
- file必需File 或 Uint8List
要存储在存储桶中的文件对象。
- fileOptions可选FileOptions
- retryAttempts可选int
设置存储客户端的 retryAttempts 参数。默认为 10。
- retryController可选StorageRetryController
传递一个 RetryController 实例并调用 `cancel()` 来取消重试尝试。
1final avatarFile = File('path/to/file');2final String fullPath = await supabase.storage.from('avatars').upload(3 'public/avatar1.png',4 avatarFile,5 fileOptions: const FileOptions(cacheControl: '3600', upsert: false),6 );替换现有文件
用新文件替换指定路径处的现有文件。
- 所需策略权限
- `buckets` 权限:无
- `objects` 权限:`update` 和 `select`
- 请参阅存储指南了解访问控制的工作原理。
参数
- path必需字符串
相对文件路径。应采用 folder/subfolder/filename.png 格式。存储桶必须在尝试更新之前存在。
- file必需File 或 Uint8List
要存储在存储桶中的文件对象。
- fileOptions可选FileOptions
- retryAttempts可选int
设置存储客户端的 retryAttempts 参数。默认为 10。
- retryController可选StorageRetryController
传递一个 RetryController 实例并调用 `cancel()` 来取消重试尝试。
1final avatarFile = File('path/to/local/file');2final String path = await supabase.storage.from('avatars').update(3 'public/avatar1.png',4 avatarFile,5 fileOptions: const FileOptions(cacheControl: '3600', upsert: false),6 );移动现有文件
移动现有文件,同时可选地重命名它。
- 所需策略权限
- `buckets` 权限:无
- `objects` 权限:`update` 和 `select`
- 请参阅存储指南了解访问控制的工作原理。
参数
- fromPath必需字符串
原始文件路径,包括当前文件名。例如 folder/image.png。
- toPath必需字符串
新文件路径,包括新文件名。例如 folder/image-new.png。
1final String result = await supabase2 .storage3 .from('avatars')4 .move('public/avatar1.png', 'private/avatar2.png');创建签名 URL
创建签名 URL 以下载文件,而无需权限。此 URL 在设定的秒数内有效。
- 所需策略权限
- `buckets` 权限:无
- `objects` 权限:`select`
- 请参阅存储指南了解访问控制的工作原理。
参数
- path必需字符串
文件路径,包括文件名。例如 folder/image.png。
- expiresIn必需int
签名 URL 过期前的秒数。例如,60 表示 URL 有效一分钟。
- transform可选TransformOptions
在将资产提供给客户端之前对其进行转换。
1final String signedUrl = await supabase2 .storage3 .from('avatars')4 .createSignedUrl('avatar1.png', 60);检索公共 URL
检索公共存储桶中资产的 URL
- 需要将存储桶设置为公共,可以通过 updateBucket() 或通过在 supabase.com/dashboard 上进入存储,点击存储桶上的溢出菜单并选择“设为公共”
- 所需策略权限
- `buckets` 权限:无
- `objects` 权限:无
- 请参阅存储指南了解访问控制的工作原理。
参数
- path必需字符串
要生成公共 URL 的文件的路径和名称。例如 folder/image.png。
- transform可选TransformOptions
在将资产提供给客户端之前对其进行转换。
1final String publicUrl = supabase2 .storage3 .from('public-bucket')4 .getPublicUrl('avatar1.png');下载文件
下载文件。
- 所需策略权限
- `buckets` 权限:无
- `objects` 权限:`select`
- 请参阅存储指南了解访问控制的工作原理。
参数
- path必需字符串
要下载文件的完整路径和文件名。例如 folder/image.png。
- transform可选TransformOptions
在将资产提供给客户端之前对其进行转换。
1final Uint8List file = await supabase2 .storage3 .from('avatars')4 .download('avatar1.png');删除存储桶中的文件
删除同一存储桶中的文件
- 所需策略权限
- `buckets` 权限:无
- `objects` 权限:`delete` 和 `select`
- 请参阅存储指南了解访问控制的工作原理。
参数
- paths必需List<String>
要删除的文件列表,包括路径和文件名。例如 ['folder/image.png']。
1final List<FileObject> objects = await supabase2 .storage3 .from('avatars')4 .remove(['avatar1.png']);列出存储桶中的所有文件
列出存储桶中的所有文件。
- 所需策略权限
- `buckets` 权限:无
- `objects` 权限:`select`
- 请参阅存储指南了解访问控制的工作原理。
参数
- path必需字符串
文件夹路径。
- searchOptions可选SearchOptions
搜索操作的选项,例如限制和偏移量。
1final List<FileObject> objects = await supabase2 .storage3 .from('avatars')4 .list();