diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts
index e8d88e24729..7e8b028d3bf 100644
--- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts
+++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.constants.ts
@@ -190,7 +190,7 @@ export const REFERENCES: References = {
dart: {
name: 'Flutter',
library: 'supabase-dart',
- versions: ['v1', 'v0'],
+ versions: ['v2', 'v1'],
icon: '/docs/img/libraries/flutter-icon.svg',
},
csharp: {
@@ -1578,14 +1578,14 @@ export const reference_javascript_v2 = {
parent: '/reference',
}
-export const reference_dart_v0 = {
+export const reference_dart_v1 = {
icon: 'reference-dart',
title: 'Flutter',
url: '/guides/reference/dart',
parent: '/reference',
}
-export const reference_dart_v1 = {
+export const reference_dart_v2 = {
icon: 'reference-dart',
title: 'Flutter',
url: '/guides/reference/dart',
diff --git a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.tsx b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.tsx
index 160b763d671..611da280cfa 100644
--- a/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.tsx
+++ b/apps/docs/components/Navigation/NavigationMenu/NavigationMenu.tsx
@@ -124,17 +124,17 @@ const menus: Menu[] = [
type: 'reference',
},
{
- id: 'reference_dart_v0',
- path: '/reference/dart/v0',
+ id: 'reference_dart_v1',
+ path: '/reference/dart/v1',
commonSectionsFile: 'common-client-libs-sections.json',
- specFile: 'supabase_dart_v0.yml',
+ specFile: 'supabase_dart_v1.yml',
type: 'reference',
},
{
- id: 'reference_dart_v1',
+ id: 'reference_dart_v2',
path: '/reference/dart',
commonSectionsFile: 'common-client-libs-sections.json',
- specFile: 'supabase_dart_v1.yml',
+ specFile: 'supabase_dart_v2.yml',
type: 'reference',
},
{
diff --git a/apps/docs/docs/ref/dart/upgrade-guide.mdx b/apps/docs/docs/ref/dart/upgrade-guide.mdx
new file mode 100644
index 00000000000..70cfa5bd823
--- /dev/null
+++ b/apps/docs/docs/ref/dart/upgrade-guide.mdx
@@ -0,0 +1,747 @@
+---
+id: upgrade-guide
+title: Upgrade to supabase_flutter v2
+description: 'Learn how to upgrade to supabase_flutter v2.'
+---
+
+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.
+
+
+
+
+ ```yaml
+ supabase_flutter: ^2.0.0
+ ```
+
+
+
+
+
+
+
+ _Optionally_ passing custom configuration to `Supabase.initialize()` is now organized into separate objects:
+
+
+
+
+
+
+
+ ```dart main.dart
+ await Supabase.initialize(
+ url: supabaseUrl,
+ anonKey: supabaseKey,
+ authFlowType: AuthFlowType.pkce,
+ storageRetryAttempts: 10,
+ realtimeClientOptions: const RealtimeClientOptions(
+ logLevel: RealtimeLogLevel.info,
+ ),
+ );
+ ```
+
+
+
+
+ ```dart main.dart
+ await Supabase.initialize(
+ url: 'SUPABASE_URL',
+ anonKey: 'SUPABASE_ANON_KEY',
+ authOptions: const FlutterAuthClientOptions(
+ authFlowType: AuthFlowType.pkce,
+ ),
+ realtimeClientOptions: const RealtimeClientOptions(
+ logLevel: RealtimeLogLevel.info,
+ ),
+ storageOptions: const StorageClientOptions(
+ retryAttempts: 10,
+ ),
+ );
+ ```
+
+
+
+
+
+
+
+
+### Auth updates
+
+
+
+
+ #### Renaming Provider to OAuthProvider
+
+ `Provider` enum is renamed to `OAuthProvider`.
+ Previously the `Provider` symbol often collided with classes in the [provider](https://pub.dev/packages/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.
+
+
+
+
+
+
+ ```dart
+ await supabase.auth.signInWithOAuth(
+ Provider.google,
+ );
+ ```
+
+
+
+ ```dart
+ await supabase.auth.signInWithOAuth(
+ OAuthProvider.google,
+ );
+ ```
+
+
+
+
+
+
+
+
+
+
+ #### Sign in with Apple method deprecated
+
+ We have removed the [sign_in_with_apple](https://pub.dev/packages/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](https://pub.dev/packages/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.
+
+
+
+
+
+ ```dart
+ await supabase.auth.signInWithApple();
+ ```
+
+
+
+ ```dart
+ Future signInWithApple() async {
+ final rawNonce = supabase.auth.generateRawNonce();
+ final hashedNonce = sha256.convert(utf8.encode(rawNonce)).toString();
+
+ final credential = await SignInWithApple.getAppleIDCredential(
+ scopes: [
+ AppleIDAuthorizationScopes.email,
+ AppleIDAuthorizationScopes.fullName,
+ ],
+ nonce: hashedNonce,
+ );
+
+ final idToken = credential.identityToken;
+ if (idToken == null) {
+ throw const AuthException(
+ 'Could not find ID Token from generated credential.',
+ );
+ }
+
+ return signInWithIdToken(
+ provider: OAuthProvider.apple,
+ idToken: idToken,
+ nonce: rawNonce,
+ );
+ }
+ ```
+
+
+
+
+
+
+
+
+
+
+ #### 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.
+
+
+
+
+
+ ```dart
+ // Session is valid, no check required
+ final session = supabase.auth.currentSession;
+ ```
+
+
+
+ ```dart
+ final session = supabase.auth.currentSession;
+
+ // Check if the session is valid.
+ final isSessionExpired = session?.isExpired;
+ ```
+
+
+
+
+
+
+
+
+
+
+
+ #### 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](https://pub.dev/packages/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](/docs/reference/dart/auth-signinwithidtoken), 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.
+
+
+
+
+
+
+ ```dart
+ // Opens a webview on iOS.
+ await supabase.auth.signInWithOAuth(
+ Provider.github,
+ authScreenLaunchMode: LaunchMode.inAppWebView,
+ context: context,
+ );
+ ```
+
+
+
+ ```dart
+ // Opens in app webview on iOS.
+ await supabase.auth.signInWithOAuth(
+ OAuthProvider.github,
+ authScreenLaunchMode: LaunchMode.inAppWebView,
+ );
+ ```
+
+
+
+
+
+
+
+
+
+
+ #### PKCE is the default auth flow type
+
+ [PKCE flow](https://supabase.com/blog/supabase-auth-sso-pkce#introducing-pkce), which is a more secure method for obtaining sessions from deep links, is now the default auth flow for any authentication involving deep links.
+
+
+
+
+
+ ```dart
+ await Supabase.initialize(
+ url: 'SUPABASE_URL',
+ anonKey: 'SUPABASE_ANON_KEY',
+ authFlowType: AuthFlowType.implicit, // set to implicit by default
+ );
+ ```
+
+
+
+ ```dart
+ await Supabase.initialize(
+ url: 'SUPABASE_URL',
+ anonKey: 'SUPABASE_ANON_KEY',
+ authOptions: FlutterAuthClientOptions(
+ authFlowType: AuthFlowType.pkce, // set to pkce 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.
+
+
+
+
+
+ ```dart
+ await Supabase.initialize(
+ url: 'SUPABASE_URL',
+ anonKey: 'SUPABASE_ANON_KEY',
+ authCallbackUrlHostname: 'auth-callback',
+ );
+ ```
+
+
+
+ ```dart
+ await Supabase.initialize(
+ url: 'SUPABASE_URL',
+ anonKey: 'SUPABASE_ANON_KEY',
+ );
+ ```
+
+
+
+
+
+
+
+
+
+
+ #### 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.
+
+
+
+
+
+ ```dart
+ // Use `initialSession` to obtain the initial session when the app starts.
+ final initialSession = await SupabaseAuth.initialSession;
+ ```
+
+
+
+ ```dart
+ // Use `currentSession` to access the session at any time.
+ final initialSession = await supabase.auth.currentSession;
+ ```
+
+
+
+
+
+
+
+### 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.
+
+
+
+
+
+
+ ```dart
+ // If you declare a query and chain filters on it
+ final 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 filter
+ final bar = await myQuery.eq('another_col', 'bar');
+ ```
+
+
+
+ ```dart
+ // Now you can declare a query and reuse it.
+ final myQuery = supabase.from('my_table').select();
+
+ final foo = await myQuery.eq('some_col', 'foo');
+
+ // The `eq` filter above is not applied to the following result
+ final bar = await myQuery.eq('another_col', 'bar');
+ ```
+
+
+
+
+
+
+
+
+
+
+ #### Renaming is and in filter
+
+ Because `is` and `in` are [reserved keywords](https://dart.dev/languages/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`.
+
+
+
+
+
+
+ ```dart
+ final data = await supabase
+ .from('users')
+ .select()
+ .is_('status', null);
+
+ final data = await supabase
+ .from('users')
+ .select()
+ .in_('status', ['ONLINE', 'OFFLINE']);
+ ```
+
+
+
+ ```dart
+ final data = await supabase
+ .from('users')
+ .select()
+ .isFilter('status', null);
+
+ final data = await supabase
+ .from('users')
+ .select()
+ .inFilter('status', ['ONLINE', 'OFFLINE']);
+ ```
+
+
+
+
+
+
+
+
+
+
+ #### 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](https://postgrest.org/en/stable/references/errors.html), which is more useful for debugging.
+
+
+
+
+
+
+ ```dart
+ try {
+ await supabase.from('countries').select();
+ } on PostgrestException catch (error) {
+ error.code; // Contains http status code
+ }
+ ```
+
+
+
+ ```dart
+ try {
+ await supabase.from('countries').select();
+ } on PostgrestException catch (error) {
+ error.code; // Contains PostgREST error 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.
+
+
+
+
+
+
+
+ ```dart
+ supabase.channel('my_channel').on(
+ RealtimeListenTypes.postgresChanges,
+ ChannelFilter(
+ event: '*',
+ schema: 'public',
+ table: 'messages',
+ filter: 'room_id=eq.200',
+ ),
+ (dynamic payload, [ref]) {
+ final Map newRecord = payload['new'];
+ final Map oldRecord = payload['old'];
+ },
+ ).subscribe();
+ ```
+
+
+
+
+ ```dart
+ supabase.channel('my_channel')
+ .onPostgresChanges(
+ event: PostgresChangeEvent.all,
+ schema: 'public',
+ table: 'messages',
+ filter: PostgresChangeFilter(
+ type: PostgresChangeFilterType.eq,
+ column: 'room_id',
+ value: 200,
+ ),
+ callback: (PostgresChangePayload payload) {
+ final Map newRecord = payload.newRecord;
+ final Map oldRecord = payload.oldRecord;
+ })
+ .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.
+
+
+
+
+
+
+
+ ```dart
+ supabase.channel('my_channel').on(
+ RealtimeListenTypes.broadcast,
+ ChannelFilter(
+ event: 'position',
+ ),
+ (dynamic payload, [ref]) {
+ print(payload);
+ },
+ ).subscribe();
+ ```
+
+
+
+
+ ```dart
+ supabase
+ .channel('my_channel')
+ .onBroadcast(
+ event: 'position',
+ callback: (Map payload) {
+ 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.
+
+
+
+
+
+
+
+ ```dart
+ final 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()});
+ }
+ },
+ );
+ ```
+
+
+
+
+ ```dart
+ final channel = supabase.channel('room1');
+
+ channel.onPresenceSync(
+ (payload) {
+ print('Synced presence state: ${channel.presenceState()}');
+ },
+ ).onPresenceJoin(
+ (payload) {
+ print('Newly joined presences $payload');
+ },
+ ).onPresenceLeave(
+ (payload) {
+ print('Newly left presences: $payload');
+ },
+ ).subscribe(
+ (status, error) async {
+ if (status == RealtimeSubscribeStatus.subscribed) {
+ await channel
+ .track({'online_at': DateTime.now().toIso8601String()});
+ }
+ },
+ );
+ ```
+
+
+
+
+
+
diff --git a/apps/docs/docs/ref/dart/v1/installing.mdx b/apps/docs/docs/ref/dart/v1/installing.mdx
new file mode 100644
index 00000000000..b279ed0dcb2
--- /dev/null
+++ b/apps/docs/docs/ref/dart/v1/installing.mdx
@@ -0,0 +1,42 @@
+---
+id: installing
+title: 'Installing'
+slug: installing
+custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml
+---
+
+### Install from pub.dev
+
+
+
+
+ You can install the Supabase package from [pub.dev](https://pub.dev/packages/supabase_flutter).
+
+
+
+
+
+
+
+
+ ```sh Terminal
+ flutter pub add supabase_flutter
+ ```
+
+
+
+
+ ```sh Terminal
+ dart pub add supabase
+ ```
+
+
+
+
+
+
diff --git a/apps/docs/docs/ref/dart/v1/introduction.mdx b/apps/docs/docs/ref/dart/v1/introduction.mdx
new file mode 100644
index 00000000000..c7c7f2f58fd
--- /dev/null
+++ b/apps/docs/docs/ref/dart/v1/introduction.mdx
@@ -0,0 +1,20 @@
+---
+id: introduction
+title: Introduction
+hideTitle: true
+---
+
+
+
+
+
Flutter Client Library
+ supabase-flutter
+
+
+
+{/* prettier-ignore */}
+
+ This reference documents every object and method available in Supabase's Flutter library, [supabase-flutter](https://pub.dev/packages/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](https://pub.dev/packages/supabase) package for non-Flutter projects.
+
diff --git a/apps/docs/docs/ref/dart/release-notes.mdx b/apps/docs/docs/ref/dart/v1/release-notes.mdx
similarity index 100%
rename from apps/docs/docs/ref/dart/release-notes.mdx
rename to apps/docs/docs/ref/dart/v1/release-notes.mdx
diff --git a/apps/docs/internals/files/reference-lib.mjs b/apps/docs/internals/files/reference-lib.mjs
index e374c9b2216..d13bd596726 100644
--- a/apps/docs/internals/files/reference-lib.mjs
+++ b/apps/docs/internals/files/reference-lib.mjs
@@ -8,7 +8,7 @@ const flatCommonLibSections = flattenSections(commonLibSections)
const clientLibFiles = [
{ fileName: 'supabase_js_v2', label: 'javascript', version: 'v2', versionSlug: false },
- { fileName: 'supabase_dart_v1', label: 'dart', version: 'v1', versionSlug: false },
+ { fileName: 'supabase_dart_v2', label: 'dart', version: 'v2', versionSlug: false },
{ fileName: 'supabase_py_v2', label: 'python', version: 'v2', versionSlug: false },
{ fileName: 'supabase_csharp_v0', label: 'csharp', version: 'v0', versionSlug: false },
{ fileName: 'supabase_swift_v1', label: 'swift', version: 'v1', versionSlug: false },
diff --git a/apps/docs/layouts/SiteLayout.tsx b/apps/docs/layouts/SiteLayout.tsx
index 545c5137910..5b5f3521eae 100644
--- a/apps/docs/layouts/SiteLayout.tsx
+++ b/apps/docs/layouts/SiteLayout.tsx
@@ -82,13 +82,13 @@ const levelsData = {
icon: '/docs/img/icons/menu/reference-javascript',
name: 'Javascript Reference v2.0',
},
- reference_dart_v0: {
- icon: '/docs/img/icons/menu/reference-dart',
- name: 'Dart Reference v0.0',
- },
reference_dart_v1: {
icon: '/docs/img/icons/menu/reference-dart',
- name: 'Dart Reference v0.0',
+ name: 'Dart Reference v1.0',
+ },
+ reference_dart_v2: {
+ icon: '/docs/img/icons/menu/reference-dart',
+ name: 'Dart Reference v2.0',
},
reference_csharp_v0: {
icon: '/docs/img/icons/menu/reference-csharp',
diff --git a/apps/docs/pages/reference/dart/[...slug].tsx b/apps/docs/pages/reference/dart/[...slug].tsx
index fb39f9d64cc..9461e3e88b0 100644
--- a/apps/docs/pages/reference/dart/[...slug].tsx
+++ b/apps/docs/pages/reference/dart/[...slug].tsx
@@ -1,5 +1,5 @@
import clientLibsCommonSections from '~/../../spec/common-client-libs-sections.json'
-import spec from '~/../../spec/supabase_dart_v1.yml' assert { type: 'yml' }
+import spec from '~/../../spec/supabase_dart_v2.yml' assert { type: 'yml' }
import RefSectionHandler from '~/components/reference/RefSectionHandler'
import { flattenSections } from '~/lib/helpers'
import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths'
diff --git a/apps/docs/pages/reference/dart/crawlers/[...slug].tsx b/apps/docs/pages/reference/dart/crawlers/[...slug].tsx
index 21c5d52b18a..f4b9ebf4308 100644
--- a/apps/docs/pages/reference/dart/crawlers/[...slug].tsx
+++ b/apps/docs/pages/reference/dart/crawlers/[...slug].tsx
@@ -1,6 +1,6 @@
import clientLibsCommonSections from '~/../../spec/common-client-libs-sections.json'
import typeSpec from '~/../../spec/enrichments/tsdoc_v2/combined.json'
-import spec from '~/../../spec/supabase_dart_v1.yml' assert { type: 'yml' }
+import spec from '~/../../spec/supabase_dart_v2.yml' assert { type: 'yml' }
import RefSectionHandler from '~/components/reference/RefSectionHandler'
import { flattenSections } from '~/lib/helpers'
import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths'
diff --git a/apps/docs/pages/reference/dart/v0/[...slug].tsx b/apps/docs/pages/reference/dart/v1/[...slug].tsx
similarity index 92%
rename from apps/docs/pages/reference/dart/v0/[...slug].tsx
rename to apps/docs/pages/reference/dart/v1/[...slug].tsx
index 86af70c75c8..782497ca5a8 100644
--- a/apps/docs/pages/reference/dart/v0/[...slug].tsx
+++ b/apps/docs/pages/reference/dart/v1/[...slug].tsx
@@ -1,5 +1,5 @@
import clientLibsCommonSections from '~/../../spec/common-client-libs-sections.json'
-import spec from '~/../../spec/supabase_dart_v0.yml' assert { type: 'yml' }
+import spec from '~/../../spec/supabase_dart_v1.yml' assert { type: 'yml' }
import RefSectionHandler from '~/components/reference/RefSectionHandler'
import { flattenSections } from '~/lib/helpers'
import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths'
diff --git a/apps/docs/pages/reference/dart/v0/crawlers/[...slug].tsx b/apps/docs/pages/reference/dart/v1/crawlers/[...slug].tsx
similarity index 95%
rename from apps/docs/pages/reference/dart/v0/crawlers/[...slug].tsx
rename to apps/docs/pages/reference/dart/v1/crawlers/[...slug].tsx
index f43ccb6a732..3a96783f3a8 100644
--- a/apps/docs/pages/reference/dart/v0/crawlers/[...slug].tsx
+++ b/apps/docs/pages/reference/dart/v1/crawlers/[...slug].tsx
@@ -1,6 +1,6 @@
import clientLibsCommonSections from '~/../../spec/common-client-libs-sections.json'
import typeSpec from '~/../../spec/enrichments/tsdoc_v2/combined.json'
-import spec from '~/../../spec/supabase_dart_v0.yml' assert { type: 'yml' }
+import spec from '~/../../spec/supabase_dart_v1.yml' assert { type: 'yml' }
import RefSectionHandler from '~/components/reference/RefSectionHandler'
import { flattenSections } from '~/lib/helpers'
import handleRefGetStaticPaths from '~/lib/mdx/handleRefStaticPaths'
diff --git a/apps/docs/scripts/search/sources/index.ts b/apps/docs/scripts/search/sources/index.ts
index b632445ba6a..15a29862f5e 100644
--- a/apps/docs/scripts/search/sources/index.ts
+++ b/apps/docs/scripts/search/sources/index.ts
@@ -47,7 +47,7 @@ export async function fetchSources() {
'dart-lib',
'/reference/dart',
{ title: 'Dart Reference' },
- '../../spec/supabase_dart_v1.yml',
+ '../../spec/supabase_dart_v2.yml',
'../../spec/common-client-libs-sections.json'
).load()
diff --git a/apps/www/lib/redirects.js b/apps/www/lib/redirects.js
index f956e6ffa57..4be0e8c6ac9 100644
--- a/apps/www/lib/redirects.js
+++ b/apps/www/lib/redirects.js
@@ -2343,4 +2343,9 @@ module.exports = [
source: '/docs/guides/auth/auth-magic-link',
destination: '/docs/guides/auth/passwordless-login/auth-magic-link',
},
+ {
+ permanent: true,
+ source: '/docs/reference/dart/sign-in-with-apple',
+ destination: '/docs/reference/dart/sign-in-with-id-token',
+ },
]
diff --git a/spec/common-client-libs-sections.json b/spec/common-client-libs-sections.json
index 13707b1ca3e..068206f7d8e 100644
--- a/spec/common-client-libs-sections.json
+++ b/spec/common-client-libs-sections.json
@@ -12,7 +12,6 @@
"type": "markdown",
"excludes": [
"reference_javascript_v1",
- "reference_dart_v0",
"reference_swift_v1"
]
},
@@ -29,8 +28,8 @@
"type": "markdown",
"excludes": [
"reference_javascript_v1",
- "reference_dart_v0",
"reference_dart_v1",
+ "reference_dart_v2",
"reference_python_v2",
"reference_csharp_v0",
"reference_swift_v1",
@@ -939,7 +938,7 @@
"title": "Misc",
"excludes": [
"reference_dart_v1",
- "reference_dart_v0",
+ "reference_dart_v2",
"reference_python_v2",
"reference_csharp_v0",
"reference_swift_v1",
@@ -955,4 +954,4 @@
}
]
}
-]
+]
\ No newline at end of file
diff --git a/spec/supabase_dart_v0.yml b/spec/supabase_dart_v0.yml
deleted file mode 100644
index d44745e7711..00000000000
--- a/spec/supabase_dart_v0.yml
+++ /dev/null
@@ -1,2403 +0,0 @@
-openref: 0.1
-
-info:
- id: reference/dart
- title: Supabase Dart Client
- description: |
-
- Supabase Dart.
-
- definition: ../../spec/enrichments/tsdoc_v1/combined.json
- slugPrefix: '/'
- specUrl: https://github.com/supabase/supabase/edit/master/spec/supabase_dart_v0.yml
- libraries:
- - name: 'Dart'
- id: 'dart'
- version: '0.0.1'
-
-functions:
- - id: installing
- title: Installing
- description: |
- ## Dart
-
- Dart libraries are built and supported by the community.
-
- ```bash
- dart pub add supabase
- ```
-
- Find the source code on [GitHub](https://github.com/supabase/supabase-dart).
-
- ## Flutter
-
- For Flutter project, you can use [supabase_flutter](https://github.com/supabase/supabase-flutter).
-
- ```bash
- flutter pub add supabase_flutter
- ```
-
- `supabase_flutter` plugin uses `supabase` plugin internally, and it adds some Flutter specific functionality such as handling deeplinks coming back from magic link verifications.
- If you are creating a Flutter application, we recommend using `supabase_flutter` instead of `supabase`.
-
- For the most part `supabase_flutter` shares the same API as `supabase` with few exceptions such as initialization or OAuth sign in.
-
- - id: initializing
- title: Initializing
- description: |
- ## Dart
- You can initialize a new Supabase client using the `SupabaseClient()` method.
-
- 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.
-
-
- ## Flutter
-
- For `supabase_flutter`, you will be using the static `initialize()` method on `Supabase` class.
-
- examples:
- - id: dart-supabase-client
- name: Dart SupabaseClient()
- code: |
- ```dart
- final supabase = SupabaseClient('https://xyzcompany.supabase.co', 'public-anon-key');
- ```
- - id: flutter-initialize
- name: Flutter initialize()
- code: |
- ```dart title="main.dart"
- Future main() async {
- await Supabase.initialize(url: 'https://xyzcompany.supabase.co', anonKey: 'public-anon-key');
- runApp(MyApp());
- }
- ```
-
- - id: sign-up
- title: 'signUp()'
- description: |
- Creates a new user.
- notes: |
- - By default, the user will need to verify their email address before logging in. If you would like to change this, you can disable "Email Confirmations" by going to Authentication -> Settings on [supabase.com/dashboard](https://supabase.com/dashboard)
- - If "Email Confirmations" is turned on, a user is returned but session will be null
- - If "Email Confirmations" is turned off, both a `user` and a `session` will be returned
- - When the user confirms their email address, they will be redirected to localhost:3000 by default. To change this, you can go to Authentication -> Settings on [supabase.com/dashboard](https://supabase.com/dashboard)
- examples:
- - id: sign-up
- name: Sign up.
- isSpotlight: true
- code: |
- ```dart
- final res = await supabase.auth.signUp('example@email.com', 'example-password');
-
- final user = res.data?.user;
- final error = res.error;
- ```
- - id: sign-up-with-third-party-providers
- name: Sign up with third-party providers.
- hideCodeBlock: true
- description: |
- If you are using Flutter, you can sign up with OAuth providers using the [`signInWithProvider()`](/docs/reference/dart/v0/auth-signinwithprovider) method available on `supabase_flutter`.
-
- - id: sign-in
- title: signIn()
- description: |
- Log in an existing user, or login via a third-party provider.
- notes: |
- - A user can sign up via email, phone number.
- - If you provide `email` without a `password`, the user will be sent a magic link.
- - The magic link's destination URL is determined by the SITE_URL config variable. To change this, you can go to Authentication -> Settings on [supabase.com/dashboard](https://supabase.com/dashboard)
- - Similarly, if you provide `phone` without a `password`, the user will be sent a one time password.
- - If you are looking to sign users in with OAuth in Flutter apps, go to [`signInWithProvider()`](/docs/reference/dart/v0/auth-signinwithprovider).
- examples:
- - id: sign-in-with-email-and-password
- name: Sign in with email.
- isSpotlight: true
- code: |
- ```dart
- final res = await supabase.auth.signIn(email: 'example@email.com', password: 'example-password');
-
- final user = res.data?.user;
- final error = res.error;
- ```
- - id: sign-in-with-magic-link
- name: Sign in with magic link.
- description: If email is provided, but no password is provided, the user will be sent a "magic link" to their email address, which they can click to open your application with a valid session. By default, a given user can only request a Magic Link once every 60 seconds.
- code: |
- ```dart
- final res = await supabase.auth.signIn(email: 'example@email.com');
-
- final error = res.error;
- ```
- - title: get-oauth-sign-in-url
- name: Get OAuth sign in URL.
- description: |
- Passing provider parameter to `signIn()` will return a URL to sign your user in via OAuth.
- If you are looking to sign in a user via OAuth on Flutter app, go to [`signInWithProvider()`](/docs/reference/dart/v0/auth-signinwithprovider).
- code: |
- ```dart
- final res = await supabase.auth.signIn(provider: Provider.github);
-
- final url = res.data?.url;
- final error = res.error;
- ```
- - id: sign-in-with-provider
- title: signInWithProvider()
- description: |
- Signs the user in using third party OAuth providers.
- notes: |
- - `auth.signInWithProvider()` is only available on `supabase_flutter`
- - It will open the browser to the relevant login page.
- examples:
- - id: sign-in-with-provider
- name: Sign in with provider.
- isSpotlight: true
- code: |
- ```dart
- final res = await supabase.auth.signInWithProvider(Provider.github);
-
- final error = res.error;
- ```
- - id: sign-in-using-a-third-party-provider-with-redirect
- name: With `redirectTo`
- description: |
- Specify the redirect link to bring back the user via deeplink.
- Note that `redirectTo` should be null for Flutter Web.
- code: |
- ```dart
- final res = await supabase.auth.signInWithProvider(
- Provider.github,
- options: AuthOptions(
- redirectTo: kIsWeb
- ? null
- : 'io.supabase.flutter://reset-callback/'),
- );
-
- final error = res.error;
- ```
- - id: sign-in-with-scopes
- name: With scopes
- description: |
- If you need additional data from an OAuth provider, you can include a space-separated list of scopes in your request to get back an OAuth provider token.
- You may also need to specify the scopes in the provider's OAuth app settings, depending on the provider.
- code: |
- ```dart
- const { user, session, error } = await supabase.auth.signIn({
- provider: 'github'
- }, {
- scopes: 'repo gist notifications'
- })
- const oAuthToken = session.provider_token // use to access provider API
- ```
- - id: sign-out
- title: signOut()
- description: |
- Signs out the current user, if there is a logged in user.
- examples:
- - id: sign-out
- name: Sign out
- isSpotlight: true
- code: |
- ```dart
- final res = await supabase.auth.signOut();
-
- final error = res.error;
- ```
- - id: session
- title: session()
- description: |
- Returns the session data, if there is an active session.
- examples:
- - name: Get the session data
- isSpotlight: true
- dart: |
- ```dart
- final session = supabase.auth.session();
- ```
-
- - id: user
- title: user()
- description: |
- Returns the user data, if there is a logged in user.
- examples:
- - name: Get the logged in user
- isSpotlight: true
- dart: |
- ```dart
- final user = supabase.auth.user();
- ```
- - id: get-session
- title: getSession()
- description: |
- Returns the session data, if there is an active session.
- examples:
- - id: get-the-session-data
- name: Get the session data
- isSpotlight: true
- code: |
- ```dart
- final session = supabase.auth.session();
- ```
- - id: get-user
- title: currentUser
- description: |
- Returns the user data, if there is a logged in user.
- examples:
- - name: Get the logged in user
- isSpotlight: true
- code: |
- ```dart
- final user = supabase.auth.user();
- ```
-
- - id: update-user
- title: updateUser()
- description: |
- Updates user data, if there is a logged in user.
- notes: |
- It's generally better to store user data in a table inside your public schema (i.e. `public.users`).
- Use the `update()` method if you have data which rarely changes or is specific only to the logged in user.
- examples:
- - id: update-the-users-metadata
- name: Update a user's metadata.
- isSpotlight: true
- code: |
- ```dart
- final res = await supabase.auth.update(
- UserAttributes(data: {'hello': 'world'})
- );
-
- final error = res.error;
- ```
-
- - id: on-auth-state-change
- title: 'onAuthStateChange()'
- description: |
- Receive a notification every time an auth event happens.
- examples:
- - id: listen-to-auth-changes
- name: Listen to auth changes
- isSpotlight: true
- code: |
- ```dart
- final subscription = supabase.auth.onAuthStateChange((event, session) {
- print(session?.user?.id);
- // handle auth state change
- });
- ```
-
- - id: reset-password-for-email
- title: Reset Password (Email)
- description: |
- Sends a reset request to an email address.
- notes: |
- Sends a reset request to an email address.
-
- When the user clicks the reset link in the email they will be forwarded to:
-
- `#access_token=x&refresh_token=y&expires_in=z&token_type=bearer&type=recovery`
-
- Your app must detect `type=recovery` in the fragment and display a password reset form to the user.
-
- You should then use the access_token in the url and new password to update the user as follows:
-
- ```dart
- final res = await supabase.auth.api.updateUser(
- accessToken,
- UserAttributes(password: 'NEW_PASSWORD'),
- );
- ```
- examples:
- - id: reset-password
- name: Reset password
- isSpotlight: true
- code: |
- ```dart
- final res = await supabase.auth.api.resetPasswordForEmail('user@example.com');
-
- final error = res.error;
- ```
- - id: reset-password-for-flutter
- name: Reset password for Flutter
- isSpotlight: true
- code: |
- You can pass `redirectTo` to open the app via deeplink when user opens the password reset email.
- ```dart
- final res = await supabase.auth.api.resetPasswordForEmail(
- 'user@example.com',
- options: AuthOptions(redirectTo: kIsWeb
- ? null
- : 'io.supabase.flutter://reset-callback/'),
- );
-
- final error = res.error;
- ```
- - id: invoke
- title: 'invoke()'
- description: |
- Invokes a Supabase Function. See the [guide](/docs/guides/functions) for details on writing Functions.
- notes: |
- - Requires an Authorization header.
- - Invoke params generally match the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) spec.
- examples:
- - id: basic-invocation
- name: Basic invocation.
- isSpotlight: true
- code: |
- ```dart
- final res = await supabaseClient.functions.invoke('hello', body: {'foo': 'baa'});
- final data = res.data;
- final error = res.error;
- ```
- - id: specifying-response-type
- name: Specifying response type.
- description: |
- By default, `invoke()` will parse the response as JSON. You can parse the response in the following formats: `json`, `blob`, `text`, and `arrayBuffer`.
- isSpotlight: true
- code: |
- ```dart
- final res = await supabaseClient.functions.invoke(
- 'hello',
- body: {'foo': 'baa'},
- responseType: ResponseType.text,
- );
- final data = res.data;
- final error = res.error;
- ```
- - id: parsing-custom-headers
- name: Parsing custom headers.
- description: |
- Any `headers` will be passed through to the function. A common pattern is to pass a logged-in user's JWT token as an Authorization header.
- isSpotlight: true
- code: |
- ```dart
- final res = await supabaseClient.functions.invoke(
- 'hello',
- body: {'foo': 'baa'},
- headers: {
- 'Authorization': 'Bearer ${supabase.auth.session()?.access_token}'
- },
- );
- ```
- - id: select
- description: |
- Performs vertical filtering with SELECT.
- title: 'Fetch data: select()'
- notes: |
- - 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 [Modifiers](/docs/reference/dart/using-modifiers)
- - `select()` can be combined with [Filters](/docs/reference/dart/using-filters)
- - If using the Supabase hosted platform `apikey` is technically a reserved keyword, since the API gateway will pluck it out for authentication. [It should be avoided as a column name](https://github.com/supabase/supabase/issues/5465).
- examples:
- - id: getting-your-data
- name: Getting your data
- isSpotlight: true
- code: |
- ```dart
- final res = await supabase
- .from('cities')
- .select()
- .execute();
-
- final data = res.data;
- final error = res.error;
- ```
- - id: selecting-specific-columns
- name: Selecting specific columns
- description: You can select specific fields from your tables.
- code: |
- ```dart
- final res = await supabase
- .from('cities')
- .select('name')
- .execute();
- ```
- - id: query-foreign-tables
- name: Query foreign tables
- description: If your database has relationships, you can query related tables too.
- code: |
- ```dart
- final res = await supabase
- .from('countries')
- .select('''
- name,
- cities (
- name
- )
- ''')
- .execute();
- ```
- - id: query-the-same-foreign-table-multiple-times
- name: Query the same foreign table multiple times
- description: |
- Sometimes you will need to query the same foreign table twice.
- In this case, you can use the name of the joined column to identify
- which join you intend to use. For convenience, you can also give an
- alias for each column. For example, if we had a shop of products,
- and we wanted to get the supplier and the purchaser at the same time
- (both in the users) table:
- code: |
- ```dart
- final res = await supabase
- .from('products')
- .select('''
- id,
- supplier:supplier_id ( name ),
- purchaser:purchaser_id ( name )
- ''')
- .execute();
- ```
- - id: filtering-with-inner-joins
- name: Filtering with inner joins
- description: |
- If you want to filter a table based on a child table's values you can use the `!inner()` function. For example, if you wanted
- to select all rows in a `message` table which belong to a user with the `username` "Jane":
- code: |
- ```dart
- final res = await supabase
- .from('messages')
- .select('*, users!inner(*)')
- .eq('users.username', 'Jane')
- .execute();
- ```
- - id: querying-with-count-option
- name: Querying with count option
- description: |
- You can get the number of rows by using the count option.
- Allowed values for count option are [exact](https://postgrest.org/en/stable/api.html#exact-count), [planned](https://postgrest.org/en/stable/api.html#planned-count) and [estimated](https://postgrest.org/en/stable/api.html#estimated-count).
- code: |
- ```dart
- final res = await supabase
- .from('cities')
- .select('name')
- .execute(count: CountOption.exact);
-
- final count = res.count;
- ```
- - id: querying-json-data
- name: Querying JSON data
- description: |
- If you have data inside of a JSONB column, you can apply select
- and query filters to the data values. Postgres offers a
- [number of operators](https://www.postgresql.org/docs/current/functions-json.html)
- for querying JSON data. Also see
- [PostgREST docs](http://postgrest.org/en/v7.0.0/api.html#json-columns) for more details.
- code: |
- ```dart
- final res = await supabase
- .from('users')
- .select('''
- id, name,
- address->street
- ''')
- .eq('address->postcode', 90210)
- .execute();
- ```
- - id: return-data-as-csv
- name: Return data as CSV
- description: |
- By default the data is returned in JSON format, however you can also request for it to be returned as Comma Separated Values.
- code: |
- ```dart
- final res = await supabase
- .from('users')
- .select()
- .csv()
- .execute();
- ```
-
- - id: insert
- description: |
- Performs an INSERT into the table.
- title: 'Create data: insert()'
- notes: |
- - By default, every time you run `insert()`, the client library will make a `select` to return the full record.
- This is convenient, but it can also cause problems if your Policies are not configured to allow the `select` operation.
- If you are using Row Level Security and you are encountering problems, try setting the `returning` param to `minimal`.
- examples:
- - id: create-a-record
- name: Create a record
- isSpotlight: true
- code: |
- ```dart
- final res = await supabase
- .from('cities')
- .insert([
- {'name': 'The Shire', 'country_id': 554}
- ]).execute();
- ```
- - id: bulk-create
- name: Bulk create
- code: |
- ```dart
- final res = await supabase
- .from('cities')
- .insert([
- {'name': 'The Shire', 'country_id': 554},
- {'name': 'Rohan', 'country_id': 555},
- ]).execute();
- ```
-
- - id: update
- description: |
- Performs an UPDATE on the table.
- title: 'Modify data: update()'
- notes: |
- - `update()` should always be combined with [Filters](/docs/reference/dart/using-filters) to target the item(s) you wish to update.
- examples:
- - id: updating-your-data
- name: Updating your data
- isSpotlight: true
- code: |
- ```dart
- final res = await supabase
- .from('cities')
- .update({ 'name': 'Middle Earth' })
- .match({ 'name': 'Auckland' })
- .execute();
- ```
- - id: updating-json-data
- name: Updating JSON data
- description: |
- Postgres offers a
- [number of operators](https://www.postgresql.org/docs/current/functions-json.html)
- for working with JSON data. Right now it is only possible to update an entire JSON document,
- but we are [working on ideas](https://github.com/PostgREST/postgrest/issues/465) for updating individual keys.
- code: |
- ```dart
- final res = await supabase
- .from('users')
- .update({
- 'address': {
- 'street': 'Melrose Place',
- 'postcode': 90210
- }
- })
- .eq('address->postcode', 90210)
- .execute();
- ```
-
- - id: upsert
- description: |
- Performs an UPSERT into the table.
- title: 'Upsert data: upsert()'
- notes: |
- - Primary keys should be included in the data payload in order for an update to work correctly.
- - Primary keys must be natural, not surrogate. There are however, [workarounds](https://github.com/PostgREST/postgrest/issues/1118) for surrogate primary keys.
- examples:
- - id: upsert-your-data
- name: Upsert your data
- isSpotlight: true
- code: |
- ```dart
- final res = await supabase
- .from('messages')
- .upsert({ 'id': 3, 'message': 'foo', 'username': 'supabot' })
- .execute();
- ```
- - id: upserting-into-tables-with-constraints
- name: Upserting into tables with constraints
- description: |
- Running the following will cause supabase to upsert data into the `users` table.
- If the username 'supabot' already exists, the `onConflict` argument tells supabase to overwrite that row
- based on the column passed into `onConflict`.
- isSpotlight: true
- code: |
- ```dart
- final res = await supabase
- .from('users')
- .upsert({ 'username': 'supabot' }, { 'onConflict': 'username' })
- .execute();
- ```
- - id: return-the-exact-number-of-rows
- name: Return the exact number of rows
- description: |
- Allowed values for count option are `exact`, `planned` and `estimated`.
- code: |
- ```dart
- final res = await supabase
- .from('users')
- .upsert({
- 'id': 3,
- 'message': 'foo',
- 'username': 'supabot'
- })
- .execute(count: CountOption.exact);
- ```
-
- - id: delete
- title: 'Delete data: delete()'
- description: |
- Performs a DELETE on the table.
- notes: |
- - `delete()` should always be combined with [Filters](/docs/reference/dart/using-filters) to target the item(s) you wish to delete.
- examples:
- - id: delete-records
- name: Delete records
- isSpotlight: true
- code: |
- ```dart
- final res = await supabase
- .from('cities')
- .delete()
- .match({ 'id': 666 })
- .execute();
- ```
-
- - id: rpc
- title: 'Stored Procedures: rpc()'
- description: |
- You can call stored procedures as a "Remote Procedure Call".
-
- That's a fancy way of saying that you can put some logic into your database then call it from anywhere.
- It's especially useful when the logic rarely changes - like password resets and updates.
- examples:
- - id: call-a-stored-procedure
- name: Call a stored procedure
- isSpotlight: true
- description: This is an example invoking a stored procedure.
- code: |
- ```dart
- final res = await supabase
- .rpc('hello_world')
- .execute();
- ```
- - id: with-parameters
- name: With Parameters
- code: |
- ```dart
- final res = await supabase
- .rpc('echo_city', params: { 'name': 'The Shire' })
- .execute();
- ```
- - id: with-count-option
- name: With count option
- description: |
- You can specify a count option to get the row count along with your data.
- Allowed values for count option are `exact`, `planned` and `estimated`.
- code: |
- ```dart
- final res = await supabase
- .rpc('hello_world')
- .execute(count: CountOption.exact);
- ```
-
- - id: subscribe
- description: |
- Subscribe to realtime changes in your database.
- title: 'on().subscribe()'
- notes: |
- - Realtime is disabled by default for new Projects for better database performance and security. You can turn it on by [managing replication](/docs/guides/database/api#managing-realtime).
- - If you want to receive the "previous" data for updates and deletes, you will need to set `REPLICA IDENTITY` to `FULL`, like this: `ALTER TABLE your_table REPLICA IDENTITY FULL;`
- examples:
- - id: listen-to-all-database-changes
- name: Listen to all database changes
- isSpotlight: true
- code: |
- ```dart
- final mySubscription = supabase
- .from('countries')
- .on(SupabaseEventTypes.all, (payload) {
- // Handle realtime payload
- })
- .subscribe();
- ```
- - id: listen-to-a-specific-table
- name: Listen to a specific table
- code: |
- ```dart
- final mySubscription = supabase
- .from('countries')
- .on(SupabaseEventTypes.all, (payload) {
- // Handle realtime payload
- })
- .subscribe();
- ```
- - id: listen-to-inserts
- name: Listen to inserts
- code: |
- ```dart
- final mySubscription = supabase
- .from('countries')
- .on(SupabaseEventTypes.insert, (payload) {
- // Handle realtime payload
- })
- .subscribe();
- ```
- - id: listen-to-updates
- name: Listen to updates
- description: |
- By default, Supabase will send only the updated record. If you want to receive the previous values as well you can
- enable full replication for the table you are listening too:
-
- ```sql
- alter table "your_table" replica identity full;
- ```
- code: |
- ```dart
- final mySubscription = supabase
- .from('countries')
- .on(SupabaseEventTypes.update, (payload) {
- // Handle realtime payload
- })
- .subscribe();
- ```
- - id: listen-to-deletes
- name: Listen to deletes
- description: |
- By default, Supabase does not send deleted records. If you want to receive the deleted record you can
- enable full replication for the table you are listening too:
-
- ```sql
- alter table "your_table" replica identity full;
- ```
- code: |
- ```dart
- final mySubscription = supabase
- .from('countries')
- .on(SupabaseEventTypes.delete, (payload) {
- // Handle realtime payload
- })
- .subscribe();
- ```
- - id: listen-to-multiple-events
- name: Listen to multiple events
- description: You can chain listeners if you want to listen to multiple events for each table.
- code: |
- ```dart
- final mySubscription = supabase
- .from('countries')
- .on(SupabaseEventTypes.insert, handleInsert)
- .on(SupabaseEventTypes.delete, handleDelete)
- .subscribe();
- ```
- - id: listening-to-row-level-changes
- name: Listen to row level changes
- description: You can listen to individual rows using the format `{table}:{col}=eq.{val}` - where `{col}` is the column name, and `{val}` is the value which you want to match.
- code: |
- ```dart
- final mySubscription = supabase
- .from('countries:id=eq.200')
- .on(SupabaseEventTypes.update, handleRecordUpdated)
- .subscribe();
- ```
-
- - id: remove-subscription
- description: |
- Removes an active subscription and returns the number of open connections.
- title: 'removeSubscription()'
- notes: |
- - Removing subscriptions is a great way to maintain the performance of your project's database. Supabase will automatically handle cleanup 30 seconds after a user is disconnected, but unused subscriptions may cause degradation as more users are simultaneously subscribed.
- examples:
- - id: remove-a-subscription
- name: Remove a subscription
- isSpotlight: true
- code: |
- ```dart
- supabase.removeSubscription(mySubscription);
- ```
-
- - id: get-subscriptions
- description: |
- Returns an array of all your subscriptions.
- title: 'getSubscriptions()'
- examples:
- - id: get-all-subscriptions
- name: Get all subscriptions
- isSpotlight: true
- code: |
- ```dart
- final subscriptions = supabase.getSubscriptions();
- ```
-
- - id: stream
- description: |
- Notifies of data at the queried table.
- title: 'stream()'
- notes: |
- - `stream()` will emit the initial data as well as any further change on the database as `Stream` of `List