Dart 参考 v2.0

Flutter客户端库

supabase_flutter在 GitHub 上查看

本参考文档记录了 Supabase 的 Flutter 库 supabase-flutter 中可用的所有对象和方法。您可以使用 supabase-flutter 与您的 Postgres 数据库交互、监听数据库更改、调用 Deno Edge Functions、构建登录和用户管理功能以及管理大文件。

我们还为非 Flutter 项目提供了 supabase 包。


安装

从 pub.dev 安装#

您可以从 pub.dev 安装 Supabase 包。

1
flutter 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 行为的选项。

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

升级指南

尽管 `supabase_flutter` v2 带来了一些突破性变更,但大部分公共 API 应该相同,只有一些细微的例外。我们在幕后进行了大量更新,使 SDK 对 Flutter 和 Dart 开发者来说工作更直观。

升级客户端库#

确保您在 `pubspec.yaml` 文件中使用 v2 客户端库。

1
supabase_flutter: ^2.0.0

(可选)向 `Supabase.initialize()` 传递自定义配置现在已组织到单独的对象中。

1
await 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,而无需任何导入前缀。

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

使用 Apple 登录方法已弃用#

我们已在 v2 中移除了 sign_in_with_apple 依赖项。这是因为并非所有开发者都需要使用 Apple 登录,我们希望减少库中的依赖项数量。

在 v2 中,如果您需要使用 Apple 登录,可以将其作为单独的依赖项导入 sign_in_with_apple。我们还添加了 `auth.generateRawNonce()` 方法,以便轻松生成安全的 nonce。

1
await supabase.auth.signInWithApple();

初始化不等待会话刷新#

在 v1 中,`Supabase.initialize()` 会在返回之前等待会话刷新。这会导致应用程序启动时间延迟,尤其是在网络环境不佳时。

在 v2 中,`Supabase.initialize()` 在从本地存储获取会话后立即返回,这使得应用程序启动更快。因此,不能保证应用程序启动时会话有效。

如果您需要确保会话有效,可以访问 `isExpired` getter 来检查会话是否有效。如果会话已过期,您可以监听 `onAuthStateChange` 事件并等待新的 `tokenRefreshed` 事件触发。

1
// Session is valid, no check required
2
final 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.
2
await supabase.auth.signInWithOAuth(
3
Provider.github,
4
authScreenLaunchMode: LaunchMode.inAppWebView,
5
context: context,
6
);

PKCE 是默认的身份验证流类型#

PKCE 流 是一种更安全的从深层链接获取会话的方法,现在是涉及深层链接的任何身份验证的默认身份验证流。

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

身份验证回调主机名参数已移除#

`Supabase.initialize()` 不再具有 `authCallbackUrlHostname` 参数。`supabase_flutter` SDK 将自动检测身份验证回调 URL 并在内部处理它们。

1
await 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.
2
final initialSession = await SupabaseAuth.initialSession;

数据方法#

插入并返回数据#

我们使查询构建器不可变,这意味着您可以重用相同的查询对象来链式调用多个过滤器并获得预期的结果。

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

重命名 is 和 in 过滤器#

由于 `is` 和 `in` 是 Dart 中的保留关键字,v1 使用 `is_` 和 `in_` 作为查询过滤器名称。用户发现下划线令人困惑,因此查询过滤器现在重命名为 `isFilter` 和 `inFilter`。

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

弃用 FetchOption,转而使用 `count()` 和 `head()` 方法#

`FetchOption()` 在 `.select()` 上现已弃用,并且新的 `.count()` 和 `head()` 方法已添加到查询构建器中。

`select()` 上的 `count()` 在执行选择的同时获取计数,而直接在 `from()` 上的 `count()` 执行 head 请求,仅获取计数。

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

PostgREST 错误代码#

API 方法抛出的 `PostgrestException` 实例具有 `code` 属性。在 v1 中,`code` 属性包含 http 状态码。

在 v2 中,`code` 属性包含 PostgREST 错误代码,这对于调试更有用。

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

实时方法#

实时方法包含最大的突破性变化。这些变化大部分是为了使接口更具类型安全性。

我们已移除 `.on()` 方法,并将其替换为 `.onPostgresChanges()`、`.onBroadcast()` 和三种不同的存在方法。

Postgres 更改#

使用新的 `.onPostgresChanges()` 方法监听数据库中的实时更改。

在 v1 中,过滤器不是强类型的,因为它们接受 `String` 类型。在 v2 中,`filter` 接受一个对象。其属性是严格类型化的,以捕获类型错误。

回调的有效载荷现在也已类型化。在 `v1` 中,有效载荷作为 `dynamic` 返回。现在它作为 `PostgresChangePayload` 对象返回。该对象包含 `oldRecord` 和 `newRecord` 属性,用于访问更改前后的数据。

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

广播#

广播现在使用专用的 `.onBroadcast()` 方法,而不是通用的 `.on()` 方法。由于该方法特定于广播,因此它接受的属性较少。

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

存在#

实时存在获得三种不同的方法来监听三种不同的存在事件:`sync`、`join` 和 `leave`。这使得回调可以严格类型化。

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

获取数据

对表或视图执行 SELECT 查询。

  • 默认情况下,Supabase 项目将返回最多 1,000 行。 可以在项目 API 设置中更改此设置。 建议将其保持较低,以限制意外或恶意请求的有效负载大小。 您可以使用 range() 查询来分页您的数据。
  • `select()` 可以与过滤器结合使用。
  • `select()` 可以与修改器结合使用。
  • apikey 如果您使用 Supabase 平台应该避免作为列名,则是一个保留关键字。

参数

  • 可选
    字符串

    要检索的列,用逗号分隔。返回时可以使用 `customName:columnName` 重命名列。

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

插入数据

对表或视图执行 INSERT 操作。

参数

  • 必需
    Map<String, dynamic> 或 List<Map<String, dynamic>>

    要插入的值。传递一个对象以插入单行,或传递一个数组以插入多行。

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

更新数据

执行 UPDATE 到表或视图。

  • `update()` 应该始终与过滤器结合使用,以定位您希望更新的项。

参数

  • 必需
    Map<String, dynamic>

    要更新的值。

1
await supabase
2
.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。

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

删除数据

执行 DELETE 到表或视图。

  • `delete()` 应该始终与过滤器结合使用,以定位您希望删除的项。
  • 如果您使用带有过滤器的 `delete()` 并且启用了 RLS,则只会删除通过 `SELECT` 策略可见的行。请注意,默认情况下没有行可见,因此您至少需要一个使行可见的 `SELECT` / `ALL` 策略。
1
await supabase
2
.from('countries')
3
.delete()
4
.eq('id', 1);

调用 Postgres 函数

执行函数调用。

您可以将 Postgres 函数作为远程过程调用执行,这是您可以在任何地方执行的数据库逻辑。当逻辑很少更改时(例如密码重置和更新),函数会很有用。

参数

  • fn
    必需
    字符串

    要调用的函数名称。

  • params
    可选
    Map<String, dynamic>

    要传递给函数调用的参数。

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

使用过滤器

过滤器允许你仅返回匹配特定条件的行。

过滤器可用于 select()update()upsert()delete() 查询。

如果数据库函数返回表响应,您还可以应用过滤器。

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

列等于一个值

仅匹配 column 等于 value 的行。

参数

  • column
    必需
    字符串

    要过滤的列。

  • value
    必需
    对象

    用于过滤的值。

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

列不等于一个值

查找所有 column 的值与指定的 value 不匹配的行。

参数

  • column
    必需
    字符串

    要过滤的列。

  • value
    必需
    对象

    用于过滤的值。

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

列大于一个值

查找所有 column 的值大于指定的 value 的行。

参数

  • column
    必需
    字符串

    要过滤的列。

  • value
    必需
    对象

    用于过滤的值。

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

列大于或等于一个值

查找所有 column 的值大于或等于指定的 value 的行。

参数

  • column
    必需
    字符串

    要过滤的列。

  • value
    必需
    对象

    用于过滤的值。

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

列小于一个值

查找所有 column 的值小于指定的 value 的行。

参数

  • column
    必需
    字符串

    要过滤的列。

  • value
    必需
    对象

    用于过滤的值。

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

列小于或等于一个值

查找所有 column 的值小于或等于指定的 value 的行。

参数

  • column
    必需
    字符串

    要过滤的列。

  • value
    必需
    对象

    用于过滤的值。

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

列匹配一个模式

查找所有 column 的值与提供的 pattern 匹配的行(区分大小写)。

参数

  • column
    必需
    字符串

    要过滤的列。

  • pattern
    必需
    字符串

    要匹配的模式。

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

列匹配一个不区分大小写的模式

查找所有 column 的值与提供的 pattern 匹配的行(不区分大小写)。

参数

  • column
    必需
    字符串

    要过滤的列。

  • pattern
    必需
    字符串

    要匹配的模式。

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

列是一个值

用于精确相等性(null、true、false)的检查,查找所有 column 的值与指定的 value 完全匹配的行。

参数

  • column
    必需
    字符串

    要过滤的列。

  • value
    必需
    Object?

    用于过滤的值。

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

列在一个数组中

查找所有 column 的值在指定的 values 中找到的行。

参数

  • column
    必需
    字符串

    要过滤的列。

  • 必需
    List

    用于过滤的 List。

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

列包含数组中的每个元素

仅适用于 jsonb、数组和范围列。仅匹配 column 包含 value 中出现的每个元素的行。

参数

  • column
    必需
    字符串

    要过滤的 jsonb、数组或范围列。

  • value
    必需
    对象

    要过滤的 jsonb、数组或范围值。

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

包含在值中

仅与 jsonb、数组和范围列相关。仅匹配 `column` 中出现的每个元素都包含在 `value` 中的行。

参数

  • column
    必需
    字符串

    要过滤的 jsonb、数组或范围列。

  • value
    必需
    对象

    要过滤的 jsonb、数组或范围值。

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

大于一个范围

仅与范围列相关。仅匹配 `column` 中的每个元素都大于 `range` 中任何元素的行。

参数

  • column
    必需
    字符串

    要过滤的范围列。

  • range
    必需
    字符串

    用于过滤的范围。

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

大于或等于一个范围

仅与范围列相关。仅匹配 `column` 中的每个元素都包含在 `range` 中或大于 `range` 中任何元素的行。

参数

  • column
    必需
    字符串

    要过滤的范围列。

  • range
    必需
    字符串

    用于过滤的范围。

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

小于一个范围

仅与范围列相关。仅匹配 `column` 中的每个元素都小于 `range` 中任何元素的行。

参数

  • column
    必需
    字符串

    要过滤的范围列。

  • range
    必需
    字符串

    用于过滤的范围。

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

小于或等于一个范围

仅与范围列相关。仅匹配 `column` 中的每个元素都包含在 `range` 中或小于 `range` 中任何元素的行。

参数

  • column
    必需
    字符串

    要过滤的范围列。

  • range
    必需
    字符串

    用于过滤的范围。

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

与范围互斥

仅与范围列相关。仅匹配 `column` 与 `range` 互斥且两个范围之间不能有任何元素的行。

参数

  • column
    必需
    字符串

    要过滤的范围列。

  • range
    必需
    字符串

    用于过滤的范围。

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

具有共同元素

仅与数组和范围列相关。仅匹配 `column` 和 `value` 有共同元素的行。

参数

  • column
    必需
    字符串

    要过滤的数组或范围列。

  • value
    必需
    对象

    要过滤的数组或范围值。

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

匹配一个字符串

查找所有 `column` 的 tsvector 值与 to_tsquery(query) 匹配的行。

参数

  • column
    必需
    字符串

    要过滤的文本或 tsvector 列。

  • query
    必需
    字符串

    要匹配的查询文本。

  • config
    可选
    字符串

    要使用的文本搜索配置。

  • type
    可选
    TextSearchType

    更改 `query` 文本的解释方式。


匹配关联值

查找所有列与指定 `query` 对象匹配的行。

参数

  • query
    必需
    Map<String, dynamic>

    用于过滤的对象,其中列名作为键映射到其过滤值。

1
final data = await supabase
2
.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 语法。

1
final data = await supabase
2
.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
    可选
    字符串

    将其设置为过滤引用表而不是父表。

1
final data = await supabase
2
.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 语法。

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

使用修饰符

过滤器在行级别工作。也就是说,它们允许您返回只匹配某些条件的行,而无需更改行的形状。修改器是所有不符合该定义的内容——允许您更改响应的格式(例如,返回 CSV 字符串)。

修饰符必须在过滤器之后指定。某些修饰符仅适用于返回行的查询(例如,select() 或返回表响应的函数的 rpc())。


插入后返回数据

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

对结果进行排序

使用指定列对结果进行排序。

参数

  • column
    必需
    字符串

    要排序的列。

  • ascending
    可选
    bool

    是否按升序排序。默认为 `false`。

  • nullsFirst
    可选
    bool

    是否将 null 排在前面。默认为 `false`。

  • referencedTable
    可选
    字符串

    在按嵌入资源中的列排序时指定引用表。

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

限制返回的行数

根据指定计数限制结果。

参数

  • count
    必需
    int

    要返回的最大行数。

  • referencedTable
    可选
    int

    将其设置为限制引用表的行而不是父表。

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

将查询限制在一个范围内

将结果限制在指定范围内的行(包括端点)。

参数

  • from
    必需
    int

    限制结果的起始索引。

  • to
    必需
    int

    限制结果的最后一个索引。

  • referencedTable
    可选
    字符串

    将其设置为限制引用表的行而不是父表。

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

检索一行数据

仅从结果中检索一行。结果必须是一行(例如使用 limit),否则将导致错误。

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

检索零行或一行数据

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

检索为 CSV

1
final data = await supabase
2
.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 记录生成信息。

1
final data = await supabase
2
.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`。

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

监听认证事件

每次发生身份验证事件时接收通知。

  • 身份验证事件类型:`AuthChangeEvent.passwordRecovery`、`AuthChangeEvent.signedIn`、`AuthChangeEvent.signedOut`、`AuthChangeEvent.tokenRefreshed`、`AuthChangeEvent.userUpdated` 和 `AuthChangeEvent.userDeleted`
1
final authSubscription = supabase.auth.onAuthStateChange.listen((data) {
2
final AuthChangeEvent event = data.event;
3
final Session? session = data.session;
4
5
print('event: $event, session: $session');
6
7
switch (event) {
8
case AuthChangeEvent.initialSession:
9
// handle initial session
10
case AuthChangeEvent.signedIn:
11
// handle signed in
12
case AuthChangeEvent.signedOut:
13
// handle signed out
14
case AuthChangeEvent.passwordRecovery:
15
// handle password recovery
16
case AuthChangeEvent.tokenRefreshed:
17
// handle token refreshed
18
case AuthChangeEvent.userUpdated:
19
// handle user updated
20
case AuthChangeEvent.userDeleted:
21
// handle user deleted
22
case AuthChangeEvent.mfaChallengeVerified:
23
// handle mfa challenge verified
24
}
25
});

创建匿名用户

创建匿名用户。

  • 返回一个匿名用户
  • 建议为匿名注册设置验证码以防止滥用。您可以在 `options` 参数中传递验证码令牌。

参数

  • data
    可选
    Map<String, dynamic>

    要存储在用户对象中的用户元数据。

  • captchaToken
    可选
    字符串

    用于验证码验证的验证码令牌。

1
await supabase.auth.signInAnonymously();

登录用户

使用电子邮件或电话号码和密码登录现有用户。

  • 需要电子邮件和密码或电话号码和密码。

参数

  • email
    可选
    字符串

    用于电子邮件身份验证的用户电子邮件地址。

  • phone
    可选
    字符串

    用于电话身份验证的用户电话号码。

  • password
    必需
    字符串

    用于身份验证的密码。

  • captchaToken
    可选
    字符串

    用于验证码验证的验证码令牌。

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

使用 ID Token 登录 (原生登录)

允许您通过与 google_sign_insign_in_with_appleflutter_facebook_auth 包结合使用,执行原生 Google、Apple 和 Facebook 登录。

参数

  • provider
    必需
    OAuthProvider

    用于执行登录的提供商。

  • idToken
    必需
    字符串

    从第三方提供商获得的身份令牌。

  • accessToken
    可选
    字符串

    从第三方提供商获得的访问令牌。Google 登录必需。

  • nonce
    可选
    字符串

    用于执行第三方登录的原始 nonce 值。Apple 登录必需。

  • captchaToken
    可选
    字符串

    用于验证码验证的验证码令牌。

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

通过 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`。

1
await 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 流的额外查询参数。

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

通过 SSO 登录用户

  • 在您可以使用此方法之前,您需要 建立与身份提供程序的连接。使用 CLI 命令 来执行此操作。
  • 如果您已将电子邮件域与身份提供程序关联,则可以使用 `domain` 属性启动登录流程。
  • 如果您需要使用不同的方式使用身份提供程序启动身份验证流程,可以使用 `providerId` 属性。例如
    • 将特定的用户电子邮件地址与身份提供程序映射。
    • 使用不同的提示来识别正确的身份提供商,例如公司特定页面、IP 地址或其他跟踪信息。

参数

  • providerId
    可选
    字符串

    用于登录的 SSO 提供商的 ID。

  • domain
    可选
    字符串

    用于登录的电子邮件域。

  • redirectTo
    可选
    字符串

    用户使用第三方提供商登录后重定向到的 URL。

  • captchaToken
    可选
    字符串

    用于验证码验证的验证码令牌。

  • launchMode
    可选
    LaunchMode

    身份验证屏幕的启动模式。默认为 `LaunchMode.platformDefault`。

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

注销用户

如果有已登录用户,则登出当前用户。

  • 为了使用 `signOut()` 方法,用户需要先登录。

参数

  • scope
    可选
    SignOutScope

    是登出所有设备还是仅登出当前设备。默认为 `SignOutScope.local`。

1
await 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
    可选
    字符串

    电子邮件链接中使用的令牌

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

获取会话

如果存在活动会话,则返回会话数据。

1
final Session? session = supabase.auth.currentSession;

获取新的会话

  • 此方法将刷新并返回新会话,无论当前会话是否过期。
1
final AuthResponse res = await supabase.auth.refreshSession();
2
final session = res.session;

获取用户

如果有已登录用户,则返回用户数据。

1
final User? user = supabase.auth.currentUser;

更新用户

更新已登录用户的用户数据。

  • 为了使用 `updateUser()` 方法,用户需要先登录。
  • 默认情况下,电子邮件更新会将确认链接发送到用户的当前电子邮件和新电子邮件。要仅将确认链接发送到用户的新的电子邮件,请在您项目的 电子邮件身份验证提供程序设置 中禁用 **安全电子邮件更改**。

参数

  • attributes
    必需
    UserAttributes

    要为用户更新的属性。

  • emailRedirectTo
    可选
    字符串

    电子邮件更新后重定向用户的 URI。

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

获取与用户关联的身份

获取链接到用户的所有身份。

  • 用户需要登录才能调用 `getUserIdentities()`。
1
final identities = await supabase.auth.getUserIdentities();

将身份与用户关联

将 OAuth 身份链接到现有用户。此方法支持 PKCE 流程。

  • 必须从您的 项目身份验证设置 中启用 **启用手动链接** 选项。
  • 需要先登录才能调用 `linkIdentity()`。
  • 如果候选身份已链接到现有用户或另一个用户,`linkIdentity()` 将失败。

参数

  • provider
    必需
    OAuthProvider

    要将身份链接到的提供商。

  • redirectTo
    可选
    字符串

    用户使用第三方提供商登录后重定向到的 URL。

  • scopes
    可选
    字符串

    要从第三方提供商请求的范围列表。

  • authScreenLaunchMode
    可选
    LaunchMode

    身份验证屏幕的启动模式。默认为 `LaunchMode.platformDefault`。

  • queryParams
    可选
    Map<String, String>

    要传递给 OAuth 流的额外查询参数。


将身份从用户取消关联

通过删除身份来取消身份与用户的关联。用户一旦取消关联,将无法再使用该身份登录。

  • 必须从您的 项目身份验证设置 中启用 **启用手动链接** 选项。
  • 用户需要已登录才能调用 unlinkIdentity()
  • 用户必须至少拥有 2 个身份才能取消关联一个身份。
  • 要取消关联的身份必须属于该用户。

参数

  • identity
    必需
    UserIdentity

    要取消关联的用户身份。


发送密码重新认证 nonce

  • 当需要更新用户的密码时,此方法与 updateUser() 结合使用。
  • 此方法向用户的电子邮件发送一个 nonce。如果用户没有确认的电子邮件地址,则该方法将 nonce 发送给用户确认的电话号码。
1
await supabase.auth.reauthenticate();

重新发送 OTP

  • 向用户重新发送注册确认、电子邮件更改或电话更改电子邮件。
  • 可以通过再次调用 `signInWithOtp()` 方法来重新发送无密码登录。
  • 可以通过再次调用 resetPasswordForEmail() 方法重新发送密码恢复电子邮件。
  • 此方法仅在发出初始注册、电子邮件更改或电话更改请求时向用户重新发送电子邮件或电话 OTP。
1
final ResendResponse res = await supabase.auth.resend(
2
type: OtpType.signup,
3
email: 'email@example.com',
4
);

设置会话数据

  • `setSession()` 接受一个刷新令牌并使用它来获取一个新会话。
  • 刷新令牌只能使用一次以获取新会话。
  • 刷新令牌轮换默认在所有项目上启用,以防止重放攻击。
  • 您可以配置 `REFRESH_TOKEN_REUSE_INTERVAL`,它提供了一个短窗口,在该窗口中,在并发或离线问题的情况下,可以多次使用相同的刷新令牌。

参数

  • refreshToken
    必需
    字符串

    用于获取新会话的刷新令牌。

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

认证 MFA

本节包含通常用于多因素身份验证 (MFA) 的方法,并在 supabase.auth.mfa 命名空间下调用。

目前,Supabase 支持基于时间的一次性密码 (TOTP) 和电话验证码作为第二因子。不支持恢复码,但用户可以注册多个因子,上限为 10 个。

拥有用于恢复的第二因子使用户免于存储恢复码的负担。它还减少了攻击面,因为通常会生成多个恢复码,而不是只有一个备份因子。

有关如何在应用程序上实施 MFA 的更多信息,请参阅我们的指南此处


注册因素

开始新多因素身份验证(MFA)因子的注册过程。此方法创建一个新的 `unverified` 因子。要验证因子,请向用户出示二维码或密钥,并要求他们将其添加到其身份验证器应用。用户必须输入其身份验证器应用中的代码才能验证它。

参数

  • factorType
    可选
    字符串

    注册因子的类型。

  • issuer
    可选
    字符串

    用户注册的域。

  • friendlyName
    可选
    字符串

    分配给因子的人性化名称。

  • phone
    可选
    字符串

    用于电话因子类型的电话号码。

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

创建挑战

准备用于验证用户是否可以访问 MFA 因子的挑战。

参数

  • factorId
    必需
    字符串

    enroll 返回的身份验证器设备的系统分配标识符。

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

验证挑战

验证挑战的代码。验证码由用户通过在身份验证器应用中输入所看到的代码提供。

参数

  • factorId
    必需
    字符串

    enroll 返回的身份验证器设备的系统分配标识符。

  • challengeId
    必需
    字符串

    要验证的挑战的 ID

  • code
    必需
    字符串

    用户身份验证器应用上的验证码

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

创建并验证挑战

辅助方法,它创建一个挑战并随后立即使用给定的代码进行验证。验证码由用户通过在身份验证器应用中输入所看到的代码提供。

参数

  • factorId
    必需
    字符串

    enroll 返回的身份验证器设备的系统分配标识符。

  • code
    必需
    字符串

    用户身份验证器应用上的验证码

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

取消注册因素

取消注册将删除 MFA 因子。用户必须具有 `aal2` 身份验证级别才能取消注册 `verified` 因子。

参数

  • factorId
    必需
    字符串

    enroll 返回的身份验证器设备的系统分配标识符。

1
final 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`。
1
final res = supabase.auth.mfa.getAuthenticatorAssuranceLevel();
2
final currentLevel = res.currentLevel;
3
final nextLevel = res.nextLevel;
4
final currentAuthenticationMethods = res.currentAuthenticationMethods;

认证 Admin

  • supabase.auth.admin 命名空间下的任何方法都需要一个 service_role 密钥。
  • 这些方法被视为管理方法,应在受信任的服务器上调用。切勿在 Flutter 应用程序中公开您的 `service_role` 密钥。
1
final supabase = SupabaseClient(supabaseUrl, serviceRoleKey);

获取用户

通过 ID 获取用户。

  • 根据用户的 ID 从数据库中获取用户对象。
  • `getUserById()` 方法需要用户的 ID,该 ID 映射到 `auth.users.id` 列。

参数

  • uid
    必需
    字符串

    要获取的用户 ID。

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

列出所有用户

获取用户列表。

  • 默认情况下,每页返回 50 个用户。

参数

  • page
    可选
    int

    要返回的用户页码。

  • page
    可选
    int

    每页要返回的用户数量。默认为 50。

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

创建用户

创建一个新用户。

  • 要确认用户的电子邮件地址或电话号码,请将 email_confirmphone_confirm 设置为 true。两个参数都默认为 false。
  • `createUser()` 不会向用户发送确认电子邮件。如果您想向他们发送电子邮件邀请,可以使用`inviteUserByEmail()`
  • 如果您确定创建用户的电子邮件或电话号码是合法的且经过验证的,则可以将 email_confirmphone_confirm 参数设置为 true

参数

  • attributes
    必需
    AdminUserAttributes

    用于创建用户的属性。

1
final 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。

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

发送电子邮件邀请链接

向用户的电子邮件地址发送邀请链接。

参数

  • email
    必需
    字符串

    要邀请的用户的电子邮件地址。

  • redirectTo
    可选
    字符串

    用户打开邀请链接后重定向到的 URI。

  • data
    可选
    Map<String, dynamic>

    用于存储用户元数据的自定义数据对象。这映射到 `auth.users.user_metadata` 列。

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


更新用户

参数

  • uid
    必需
    GenerateLinkType

    要更新的用户 ID。

  • attributes
    必需
    AdminUserAttributes

    要为用户更新的属性。

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

调用 Supabase 边缘函数。

调用 Supabase 函数。请参阅 指南 以了解有关编写函数的详细信息。

  • 需要 Authorization 标头。
  • Invoke 参数通常与 Fetch API 规范相匹配。

参数

  • functionName
    必需
    字符串

    要调用的函数名称。

  • headers
    可选
    Map<String, String>

    要随请求发送的自定义标头。

  • body
    可选
    Map<String, String>

    请求正文。

  • method
    可选
    HttpMethod

    请求的 HTTP 方法。默认为 POST。

1
final res = await supabase.functions.invoke('hello', body: {'foo': 'baa'});
2
final 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])` 监听列是其中一个值的行
1
supabase.from('countries')
2
.stream(primaryKey: ['id'])
3
.listen((List<Map<String, dynamic>> data) {
4
// Do something awesome with the data
5
});

订阅频道

订阅数据库中的实时更改。

  • 新表的实时功能默认禁用。您可以通过管理复制来启用它。
  • 如果您想接收更新和删除的“先前”数据,则需要将 REPLICA IDENTITY 设置为 FULL,如下所示:ALTER TABLE your_table REPLICA IDENTITY FULL;
1
supabase
2
.channel('public:countries')
3
.onPostgresChanges(
4
event: PostgresChangeEvent.all,
5
schema: 'public',
6
table: 'countries',
7
callback: (payload) {
8
print('Change received: ${payload.toString()}');
9
})
10
.subscribe();

取消订阅频道

取消订阅并从实时客户端中删除实时通道。

  • 删除频道是维护项目实时服务性能以及数据库性能的好方法(如果你正在侦听 Postgres 更改)。Supabase 会在客户端断开连接 30 秒后自动处理清理,但未使用的频道可能会导致更多客户端同时订阅而导致性能下降。
1
final status = await supabase.removeChannel(channel);

取消订阅所有频道

取消订阅并从实时客户端删除所有实时通道。

  • 删除频道是维护项目实时服务性能以及数据库性能的好方法(如果你正在侦听 Postgres 更改)。Supabase 会在客户端断开连接 30 秒后自动处理清理,但未使用的频道可能会导致更多客户端同时订阅而导致性能下降。
1
final statuses = await supabase.removeAllChannels();

获取所有频道

返回所有实时通道。

1
final channels = supabase.getChannels();

文件存储

本节包含处理文件存储桶的方法。


列出所有存储桶

检索现有产品中所有存储桶的详细信息。

  • 所需策略权限
    • `buckets` 权限:`select`
    • `objects` 权限:无
  • 请参阅存储指南了解访问控制的工作原理。
1
final List<Bucket> buckets = await supabase
2
.storage
3
.listBuckets();

检索存储桶

检索现有的存储存储桶的详细信息。

  • 所需策略权限
    • `buckets` 权限:`select`
    • `objects` 权限:无
  • 请参阅存储指南了解访问控制的工作原理。

参数

  • id
    必需
    字符串

    你要检索的存储桶的唯一标识符。

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

创建存储桶

创建一个新的存储存储桶

  • 所需策略权限
    • `buckets` 权限:`insert`
    • `objects` 权限:无
  • 请参阅存储指南了解访问控制的工作原理。

参数

  • id
    必需
    字符串

    你要创建的存储桶的唯一标识符。

  • bucketOptions
    可选
    BucketOptions

    一个可选参数,用于使存储桶公开。

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

清空存储桶

删除单个存储桶中的所有对象。

  • 所需策略权限
    • `buckets` 权限:`select`
    • `objects` 权限:`select` 和 `delete`
  • 请参阅存储指南了解访问控制的工作原理。

参数

  • id
    必需
    字符串

    要清空存储桶的唯一标识符。

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

更新存储桶

更新新的存储桶

  • 所需策略权限
    • `buckets` 权限:`update`
    • `objects` 权限:无
  • 请参阅存储指南了解访问控制的工作原理。

参数

  • id
    必需
    字符串

    要更新存储桶的唯一标识符。

  • bucketOptions
    必需
    BucketOptions

    一个可选参数,用于使存储桶公开。

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

删除存储桶

删除现有的存储桶。如果存储桶内存在现有对象,则无法删除存储桶。你必须首先 empty() 存储桶。

  • 所需策略权限
    • `buckets` 权限:`select` 和 `delete`
    • `objects` 权限:无
  • 请参阅存储指南了解访问控制的工作原理。

参数

  • id
    必需
    字符串

    要删除存储桶的唯一标识符。

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

上传文件

将文件上传到现有的存储桶。

  • 所需策略权限
    • `buckets` 权限:无
    • `objects` 权限:`insert`
  • 请参阅存储指南了解访问控制的工作原理。

参数

  • path
    必需
    字符串

    相对文件路径。应采用 folder/subfolder/filename.png 格式。存储桶必须在尝试更新之前存在。

  • file
    必需
    File 或 Uint8List

    要存储在存储桶中的文件对象。

  • fileOptions
    可选
    FileOptions
  • retryAttempts
    可选
    int

    设置存储客户端的 retryAttempts 参数。默认为 10。

  • retryController
    可选
    StorageRetryController

    传递一个 RetryController 实例并调用 `cancel()` 来取消重试尝试。

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

替换现有文件

用新文件替换指定路径处的现有文件。

  • 所需策略权限
    • `buckets` 权限:无
    • `objects` 权限:`update` 和 `select`
  • 请参阅存储指南了解访问控制的工作原理。

参数

  • path
    必需
    字符串

    相对文件路径。应采用 folder/subfolder/filename.png 格式。存储桶必须在尝试更新之前存在。

  • file
    必需
    File 或 Uint8List

    要存储在存储桶中的文件对象。

  • fileOptions
    可选
    FileOptions
  • retryAttempts
    可选
    int

    设置存储客户端的 retryAttempts 参数。默认为 10。

  • retryController
    可选
    StorageRetryController

    传递一个 RetryController 实例并调用 `cancel()` 来取消重试尝试。

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

移动现有文件

移动现有文件,同时可选地重命名它。

  • 所需策略权限
    • `buckets` 权限:无
    • `objects` 权限:`update` 和 `select`
  • 请参阅存储指南了解访问控制的工作原理。

参数

  • fromPath
    必需
    字符串

    原始文件路径,包括当前文件名。例如 folder/image.png。

  • toPath
    必需
    字符串

    新文件路径,包括新文件名。例如 folder/image-new.png。

1
final String result = await supabase
2
.storage
3
.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

    在将资产提供给客户端之前对其进行转换。

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

检索公共 URL

检索公共存储桶中资产的 URL

  • 需要将存储桶设置为公共,可以通过 updateBucket() 或通过在 supabase.com/dashboard 上进入存储,点击存储桶上的溢出菜单并选择“设为公共”
  • 所需策略权限
    • `buckets` 权限:无
    • `objects` 权限:无
  • 请参阅存储指南了解访问控制的工作原理。

参数

  • path
    必需
    字符串

    要生成公共 URL 的文件的路径和名称。例如 folder/image.png。

  • transform
    可选
    TransformOptions

    在将资产提供给客户端之前对其进行转换。

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

下载文件

下载文件。

  • 所需策略权限
    • `buckets` 权限:无
    • `objects` 权限:`select`
  • 请参阅存储指南了解访问控制的工作原理。

参数

  • path
    必需
    字符串

    要下载文件的完整路径和文件名。例如 folder/image.png。

  • transform
    可选
    TransformOptions

    在将资产提供给客户端之前对其进行转换。

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

删除存储桶中的文件

删除同一存储桶中的文件

  • 所需策略权限
    • `buckets` 权限:无
    • `objects` 权限:`delete` 和 `select`
  • 请参阅存储指南了解访问控制的工作原理。

参数

  • paths
    必需
    List<String>

    要删除的文件列表,包括路径和文件名。例如 ['folder/image.png']。

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

列出存储桶中的所有文件

列出存储桶中的所有文件。

  • 所需策略权限
    • `buckets` 权限:无
    • `objects` 权限:`select`
  • 请参阅存储指南了解访问控制的工作原理。

参数

  • path
    必需
    字符串

    文件夹路径。

  • searchOptions
    可选
    SearchOptions

    搜索操作的选项,例如限制和偏移量。

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