mirror of
https://github.com/supabase/supabase.git
synced 2026-10-06 01:45:10 +03:00
fix: apply redirect for links to the old Dart docs (#9724)
* fix: update some old flutter code to the current version * feat: add flutter upgrade guides until stream * fix: make primaryKey named parameter in flutter docs * complete flutter upgrade guide * add redirects for incoming traffic for old dart docs
This commit is contained in:
1 parent
e2ab4fe590
commit
66df16cdff
4 files changed
+591
-56
No files matched your search
@@ -0,0 +1,499 @@
|
||||
---
|
||||
id: upgrade-guide
|
||||
title: Upgrade to supabase-flutter v1
|
||||
description: 'Learn how to upgrade to supabase-flutter v1.'
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs'
|
||||
import TabItem from '@theme/TabItem'
|
||||
|
||||
supabase-flutter focuses on improving the developer experience and making it easier to use. This guide will help you upgrade from supabase-flutter v0 to v1.
|
||||
|
||||
## Upgrade the client library
|
||||
|
||||
Update the package in your pubspec.yaml file.
|
||||
|
||||
```yaml
|
||||
supabase_flutter: ^1.0.0
|
||||
```
|
||||
|
||||
## Error handling
|
||||
|
||||
The way supabase-flutter throws error has changed in v1. In v0, errors were returned as a response. In v1, errors are thrown as exceptions. This makes it more intuitive as a Flutter developer to handle errors.
|
||||
|
||||
|
||||
<Tabs
|
||||
groupId="version"
|
||||
values={[
|
||||
{label: 'Before', value: '0.x'},
|
||||
{label: 'After', value: '1.x'},
|
||||
]}>
|
||||
|
||||
<TabItem value="0.x">
|
||||
|
||||
```dart
|
||||
final res = await supabase.from('my_table').select().execute();
|
||||
final error = res.error;
|
||||
if(error != null) {
|
||||
// handle error
|
||||
}
|
||||
final data = res.data;
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="1.x">
|
||||
|
||||
```dart
|
||||
try {
|
||||
final data = supabase.from('my_table').select();
|
||||
} catch (error) {
|
||||
// handle error
|
||||
}
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
|
||||
|
||||
## Auth methods
|
||||
|
||||
The signIn() method has been deprecated in favor of more explicit method signatures to help with type hinting. Previously it was difficult for developers to know what they were missing (e.g., a lot of developers didn't realize they could use passwordless magic links).
|
||||
|
||||
### Listening to auth state change
|
||||
|
||||
`onAuthStateChange` now returns a `Stream`.
|
||||
|
||||
<Tabs
|
||||
groupId="version"
|
||||
values={[
|
||||
{label: 'Before', value: '0.x'},
|
||||
{label: 'After', value: '1.x'},
|
||||
]}>
|
||||
|
||||
<TabItem value="0.x">
|
||||
|
||||
```dart
|
||||
final authSubscription = supabase.auth.onAuthStateChange((event, session) {
|
||||
// handle auth state change
|
||||
});
|
||||
|
||||
// Unsubscribe when no longer needed
|
||||
authSubscription.data?.unsubscribe();
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="1.x">
|
||||
|
||||
```dart
|
||||
final authSubscription = supabase.auth.onAuthStateChange.listen((data) {
|
||||
final AuthChangeEvent event = data.event;
|
||||
final Session? session = data.session;
|
||||
// handle auth state change
|
||||
});
|
||||
|
||||
// Unsubscribe when no longer needed
|
||||
authSubscription.cancel();
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Sign in with email and password
|
||||
|
||||
<Tabs
|
||||
groupId="version"
|
||||
values={[
|
||||
{label: 'Before', value: '0.x'},
|
||||
{label: 'After', value: '1.x'},
|
||||
]}>
|
||||
|
||||
<TabItem value="0.x">
|
||||
|
||||
```dart
|
||||
await supabase.auth.signIn(email: email, password: password);
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="1.x">
|
||||
|
||||
```dart
|
||||
await supabase.auth.signInWithPassword(email: email, password: password);
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Sign in with magic link
|
||||
<Tabs
|
||||
groupId="version"
|
||||
values={[
|
||||
{label: 'Before', value: '0.x'},
|
||||
{label: 'After', value: '1.x'},
|
||||
]}>
|
||||
|
||||
<TabItem value="0.x">
|
||||
|
||||
```dart
|
||||
await supabase.auth.signIn(email: email);
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="1.x">
|
||||
|
||||
```dart
|
||||
await supabase.auth.signInWithOtp(email: email);
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Sign in with a third-party OAuth provider
|
||||
<Tabs
|
||||
groupId="version"
|
||||
values={[
|
||||
{label: 'Before', value: '0.x'},
|
||||
{label: 'After', value: '1.x'},
|
||||
]}>
|
||||
|
||||
<TabItem value="0.x">
|
||||
|
||||
```dart
|
||||
await supabase.auth.signInWithProvider(
|
||||
Provider.github,
|
||||
options: AuthOptions(
|
||||
redirectTo: kIsWeb
|
||||
? null
|
||||
: 'io.supabase.flutter://reset-callback/'),
|
||||
);
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="1.x">
|
||||
|
||||
```dart
|
||||
await supabase.auth.signInWithOAuth(
|
||||
Provider.github,
|
||||
redirectTo: kIsWeb ? null : 'io.supabase.flutter://reset-callback/',
|
||||
);
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Sign in with phone
|
||||
<Tabs
|
||||
groupId="version"
|
||||
values={[
|
||||
{label: 'Before', value: '0.x'},
|
||||
{label: 'After', value: '1.x'},
|
||||
]}>
|
||||
|
||||
<TabItem value="0.x">
|
||||
|
||||
```dart
|
||||
await supabase.auth.signIn(
|
||||
phone: '+13334445555',
|
||||
password: 'example-password',
|
||||
);
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="1.x">
|
||||
|
||||
```dart
|
||||
await supabase.auth.signInWithPassword(
|
||||
phone: '+13334445555',
|
||||
password: 'example-password',
|
||||
);
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Sign in with phone using OTP
|
||||
<Tabs
|
||||
groupId="version"
|
||||
values={[
|
||||
{label: 'Before', value: '0.x'},
|
||||
{label: 'After', value: '1.x'},
|
||||
]}>
|
||||
|
||||
<TabItem value="0.x">
|
||||
|
||||
```dart
|
||||
final res = await supabase.auth.signIn(phone: phone);
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="1.x">
|
||||
|
||||
```dart
|
||||
await supabase.auth.signInWithOtp(
|
||||
phone: phone,
|
||||
);
|
||||
|
||||
// After receiving a SMS with a OTP.
|
||||
await supabase.auth.verifyOTP(
|
||||
type: OtpType.sms,
|
||||
token: token,
|
||||
phone: phone,
|
||||
);
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Reset password for email
|
||||
<Tabs
|
||||
groupId="version"
|
||||
values={[
|
||||
{label: 'Before', value: '0.x'},
|
||||
{label: 'After', value: '1.x'},
|
||||
]}>
|
||||
|
||||
<TabItem value="0.x">
|
||||
|
||||
```dart
|
||||
await supabase.auth.api.resetPasswordForEmail(
|
||||
email,
|
||||
options:
|
||||
AuthOptions(redirectTo: 'io.supabase.flutter://reset-callback/'),
|
||||
);
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="1.x">
|
||||
|
||||
```dart
|
||||
await supabase.auth.resetPasswordForEmail(
|
||||
email,
|
||||
redirectTo: kIsWeb ? null : 'io.supabase.flutter://reset-callback/',
|
||||
);
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Get the user's current session
|
||||
<Tabs
|
||||
groupId="version"
|
||||
values={[
|
||||
{label: 'Before', value: '0.x'},
|
||||
{label: 'After', value: '1.x'},
|
||||
]}>
|
||||
|
||||
<TabItem value="0.x">
|
||||
|
||||
```dart
|
||||
final session = supabase.auth.session();
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="1.x">
|
||||
|
||||
```dart
|
||||
final Session? session = supabase.auth.currentSession;
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Get the logged-in user
|
||||
<Tabs
|
||||
groupId="version"
|
||||
values={[
|
||||
{label: 'Before', value: '0.x'},
|
||||
{label: 'After', value: '1.x'},
|
||||
]}>
|
||||
|
||||
<TabItem value="0.x">
|
||||
|
||||
```dart
|
||||
final user = supabase.auth.user();
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="1.x">
|
||||
|
||||
```dart
|
||||
final User? user = supabase.auth.currentUser;
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Update user data for a logged-in user
|
||||
<Tabs
|
||||
groupId="version"
|
||||
values={[
|
||||
{label: 'Before', value: '0.x'},
|
||||
{label: 'After', value: '1.x'},
|
||||
]}>
|
||||
|
||||
<TabItem value="0.x">
|
||||
|
||||
```dart
|
||||
await supabase.auth.update(
|
||||
UserAttributes(data: {'hello': 'world'})
|
||||
);
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="1.x">
|
||||
|
||||
```dart
|
||||
await supabase.updateUser(
|
||||
UserAttributes(
|
||||
data: { 'hello': 'world' },
|
||||
),
|
||||
);
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Data methods
|
||||
|
||||
`.insert()` / `.upsert()` / `.update()` / `.delete()` don't return rows by default.
|
||||
|
||||
Previously, these methods return inserted/updated/deleted rows by default (which caused [some confusion](https://github.com/supabase/supabase/discussions/1548)), and you can opt to not return it by specifying `returning: 'minimal'`. Now the default behavior is to not return rows. To return inserted/updated/deleted rows, add a `.select()` call at the end.
|
||||
|
||||
Also, calling `.execute()` at the end of the query was a requirement in v0, but in v1 `.execute` is deperecated.
|
||||
|
||||
### Insert without returning inserted data
|
||||
|
||||
<Tabs
|
||||
groupId="version"
|
||||
values={[
|
||||
{label: 'Before', value: '0.x'},
|
||||
{label: 'After', value: '1.x'},
|
||||
]}>
|
||||
|
||||
<TabItem value="0.x">
|
||||
|
||||
```dart
|
||||
await supabase
|
||||
.from('my_table')
|
||||
.insert(data, returning: ReturningOption.minimal)
|
||||
.execute();
|
||||
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="1.x">
|
||||
|
||||
```dart
|
||||
await supabase.from('my_table').insert(data);
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Insert with returning inserted data
|
||||
|
||||
<Tabs
|
||||
groupId="version"
|
||||
values={[
|
||||
{label: 'Before', value: '0.x'},
|
||||
{label: 'After', value: '1.x'},
|
||||
]}>
|
||||
|
||||
<TabItem value="0.x">
|
||||
|
||||
```dart
|
||||
final res = await supabase
|
||||
.from('my_table')
|
||||
.insert(data)
|
||||
.execute();
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="1.x">
|
||||
|
||||
```dart
|
||||
final insertedData = await supabase.from('my_table').insert(data).select();
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Realtime methods
|
||||
|
||||
### Stream
|
||||
|
||||
`.stream()` no longer needs the `.execute()` at the end. Also, filtering by `eq` is a lot easier now. `primaryKey` is now a named parameter to make it more obvious what to pass.
|
||||
|
||||
<Tabs
|
||||
groupId="version"
|
||||
values={[
|
||||
{label: 'Before', value: '0.x'},
|
||||
{label: 'After', value: '1.x'},
|
||||
]}>
|
||||
|
||||
<TabItem value="0.x">
|
||||
|
||||
```dart
|
||||
supabase.from('my_table:id=eq.120')
|
||||
.stream(['id'])
|
||||
.listen();
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="1.x">
|
||||
|
||||
```dart
|
||||
supabase.from('my_table')
|
||||
.stream(primaryKey: ['id'])
|
||||
.eq('id', '120')
|
||||
.listen();
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Subscribe
|
||||
|
||||
<Tabs
|
||||
groupId="version"
|
||||
values={[
|
||||
{label: 'Before', value: '0.x'},
|
||||
{label: 'After', value: '1.x'},
|
||||
]}>
|
||||
|
||||
<TabItem value="0.x">
|
||||
|
||||
```dart
|
||||
final subscription = supabase
|
||||
.from('countries')
|
||||
.on(SupabaseEventTypes.all, (payload) {
|
||||
// Handle realtime payload
|
||||
})
|
||||
.subscribe();
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="1.x">
|
||||
|
||||
```dart
|
||||
final channel = supabase.channel('*');
|
||||
channel.on(
|
||||
RealtimeListenTypes.postgresChanges,
|
||||
ChannelFilter(event: '*', schema: '*'),
|
||||
(payload, [ref]) {
|
||||
// Handle realtime payload
|
||||
},
|
||||
).subscribe();
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Unsubscribe
|
||||
|
||||
<Tabs
|
||||
groupId="version"
|
||||
values={[
|
||||
{label: 'Before', value: '0.x'},
|
||||
{label: 'After', value: '1.x'},
|
||||
]}>
|
||||
|
||||
<TabItem value="0.x">
|
||||
|
||||
```dart
|
||||
supabase.removeSubscription(subscription);
|
||||
```
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="1.x">
|
||||
|
||||
```dart
|
||||
await supabase.removeChannel(channel);
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
@@ -6,7 +6,7 @@ const sidebars = {
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Getting Started',
|
||||
items: ['intro', 'installing', 'initializing'],
|
||||
items: ['intro', 'installing', 'initializing', 'upgrade-guide'],
|
||||
collapsed: true,
|
||||
},
|
||||
{
|
||||
@@ -23,7 +23,7 @@ const sidebars = {
|
||||
'generated/auth-currentuser',
|
||||
'generated/auth-updateuser',
|
||||
'generated/auth-onauthstatechange',
|
||||
'generated/reset-password-email',
|
||||
'generated/auth-resetpasswordforemail',
|
||||
],
|
||||
collapsed: true,
|
||||
},
|
||||
|
||||
@@ -1475,4 +1475,59 @@ module.exports = [
|
||||
source: '/docs/reference/javascript/getsubscriptions',
|
||||
destination: '/docs/reference/javascript/v1/getsubscriptions',
|
||||
},
|
||||
|
||||
// supabase-flutter v0 to v1 redirects
|
||||
// v0: /auth-update
|
||||
// v1: /auth-updateuser
|
||||
{
|
||||
permanent: true,
|
||||
source: '/docs/reference/dart/auth-update',
|
||||
destination: '/docs/reference/dart/auth-updateuser',
|
||||
},
|
||||
// v0: /auth-api-resetpasswordforemail
|
||||
// v1: /auth-resetpasswordforemail
|
||||
{
|
||||
permanent: true,
|
||||
source: '/docs/reference/dart/reset-password-email',
|
||||
destination: '/docs/reference/dart/auth-resetpasswordforemail',
|
||||
},
|
||||
// signIn method is now split into signInWithPassword ,signInWithPasswordless ,signInWithOAuth
|
||||
// send traffic to v0 docs instead
|
||||
{
|
||||
permanent: true,
|
||||
source: '/docs/reference/dart/auth-signin',
|
||||
destination: '/docs/reference/dart/v0/auth-signin',
|
||||
},
|
||||
// v0: /auth-session
|
||||
// v1: /auth-currentsession
|
||||
{
|
||||
permanent: true,
|
||||
source: '/docs/reference/dart/auth-session',
|
||||
destination: '/docs/reference/dart/auth-currentsession',
|
||||
},
|
||||
// v0: /auth-user
|
||||
// v1: /auth-currentuser
|
||||
{
|
||||
permanent: true,
|
||||
source: '/docs/reference/dart/auth-user',
|
||||
destination: '/docs/reference/dart/auth-currentuser',
|
||||
},
|
||||
// v0: /auth-signinwithprovider
|
||||
// v1: /auth-signinwithoauth
|
||||
{
|
||||
permanent: true,
|
||||
source: '/docs/reference/dart/v0/auth-signinwithprovider',
|
||||
destination: '/docs/reference/dart/auth-signinwithoauth',
|
||||
},
|
||||
// realtime methods been replaced with new names
|
||||
{
|
||||
permanent: true,
|
||||
source: '/docs/reference/dart/removesubscription',
|
||||
destination: '/docs/reference/dart/v0/removesubscription',
|
||||
},
|
||||
{
|
||||
permanent: true,
|
||||
source: '/docs/reference/dart/getsubscriptions',
|
||||
destination: '/docs/reference/dart/v0/getsubscriptions',
|
||||
},
|
||||
]
|
||||
+35
-54
@@ -100,7 +100,7 @@ pages:
|
||||
dart: |
|
||||
```dart
|
||||
await supabase.auth.signInWithOtp(
|
||||
phone: 'example@email.com',
|
||||
phone: '+13334445555',
|
||||
);
|
||||
```
|
||||
auth.signInWithOAuth():
|
||||
@@ -115,7 +115,7 @@ pages:
|
||||
isSpotlight: true
|
||||
dart: |
|
||||
```dart
|
||||
await supabase.auth.signInWithProvider(Provider.github);
|
||||
await supabase.auth.signInWithOAuth(Provider.github);
|
||||
```
|
||||
- name: With `redirectTo`
|
||||
description: |
|
||||
@@ -123,11 +123,9 @@ pages:
|
||||
Note that `redirectTo` should be null for Flutter Web.
|
||||
dart: |
|
||||
```dart
|
||||
await supabase.auth.signInWithProvider(
|
||||
await supabase.auth.signInWithOAuth(
|
||||
Provider.github,
|
||||
options: const AuthOptions(
|
||||
redirectTo: kIsWeb ? null : 'io.supabase.flutter://reset-callback/',
|
||||
),
|
||||
redirectTo: kIsWeb ? null : 'io.supabase.flutter://reset-callback/',
|
||||
);
|
||||
```
|
||||
- name: With scopes
|
||||
@@ -136,8 +134,10 @@ pages:
|
||||
You may also need to specify the scopes in the provider's OAuth app settings, depending on the provider.
|
||||
dart: |
|
||||
```dart
|
||||
await supabase.auth.signInWithProvider(Provider.github,
|
||||
options: const AuthOptions(scopes: 'repo gist notifications'));
|
||||
await supabase.auth.signInWithOAuth(
|
||||
Provider.github,
|
||||
scopes: 'repo gist notifications'
|
||||
);
|
||||
...
|
||||
// after user comes back from signin flow
|
||||
|
||||
@@ -263,71 +263,52 @@ pages:
|
||||
isSpotlight: true
|
||||
dart: |
|
||||
```dart
|
||||
final subscription = supabase.auth.onAuthStateChange(
|
||||
(event, session) {
|
||||
print(session?.user.id);
|
||||
// handle auth state change
|
||||
},
|
||||
);
|
||||
final authSubscription = supabase.auth.onAuthStateChange.listen((data) {
|
||||
final AuthChangeEvent event = data.event;
|
||||
final Session? session = data.session;
|
||||
});
|
||||
```
|
||||
- name: Listen to a specific event
|
||||
dart: |
|
||||
```dart
|
||||
final subscription = supabase.auth.onAuthStateChange(
|
||||
(event, session) {
|
||||
if (event == AuthChangeEvent.signedIn) {
|
||||
print(session?.user.id);
|
||||
// handle signIn
|
||||
}
|
||||
},
|
||||
);
|
||||
final authSubscription = supabase.auth.onAuthStateChange.listen((data) {
|
||||
final AuthChangeEvent event = data.event;
|
||||
if (event == AuthChangeEvent.signedIn) {
|
||||
// handle signIn
|
||||
}
|
||||
});
|
||||
```
|
||||
- name: Unsubscribe from auth subscription
|
||||
dart: |
|
||||
```dart
|
||||
final subscription = supabase.auth.onAuthStateChange((event, session) {});
|
||||
final authSubscription = supabase.auth.onAuthStateChange((event, session) {});
|
||||
|
||||
subscription.data?.unsubscribe();
|
||||
authSubscription.cancel();
|
||||
```
|
||||
Reset Password (Email):
|
||||
auth.resetPasswordForEmail:
|
||||
title: 'resetPasswordForEmail()'
|
||||
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:
|
||||
|
||||
`<SITE_URL>#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:
|
||||
Sends a password reset request to an email address. When the user clicks the reset link in the email they are redirected back to your application. Prompt the user for a new password and call auth.updateUser():
|
||||
|
||||
```dart
|
||||
final res = await supabase.auth.api.updateUser(
|
||||
accessToken,
|
||||
UserAttributes(password: 'NEW_PASSWORD'),
|
||||
await supabase.auth.resetPasswordForEmail(
|
||||
'sample@email.com',
|
||||
redirectTo: kIsWeb ? null : 'io.supabase.flutter://reset-callback/',
|
||||
);
|
||||
```
|
||||
examples:
|
||||
- name: Reset password for Flutter
|
||||
isSpotlight: true
|
||||
dart: |
|
||||
You can pass `redirectTo` to open the app via deeplink when user opens the password reset email.
|
||||
`redirectTo` is used 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/'),
|
||||
await supabase.auth.resetPasswordForEmail(
|
||||
'sample@email.com',
|
||||
redirectTo: kIsWeb ? null : 'io.supabase.flutter://reset-callback/',
|
||||
);
|
||||
```
|
||||
- name: Reset password
|
||||
isSpotlight: true
|
||||
dart: |
|
||||
```dart
|
||||
final res = await supabase.auth.api.resetPasswordForEmail('user@example.com');
|
||||
```
|
||||
invoke():
|
||||
title: 'invoke()'
|
||||
description: |
|
||||
@@ -782,7 +763,7 @@ pages:
|
||||
dart: |
|
||||
```dart
|
||||
supabase.from('countries')
|
||||
.stream(['id'])
|
||||
.stream(primaryKey: ['id'])
|
||||
.listen((List<Map<String, dynamic>> data) {
|
||||
// Do something awesome with the data
|
||||
});
|
||||
@@ -794,7 +775,7 @@ pages:
|
||||
dart: |
|
||||
```dart
|
||||
supabase.from('countries')
|
||||
.stream(['id'])
|
||||
.stream(primaryKey: ['id'])
|
||||
.eq('id', '120')
|
||||
.listen((List<Map<String, dynamic>> data) {
|
||||
// Do something awesome with the data
|
||||
@@ -804,7 +785,7 @@ pages:
|
||||
dart: |
|
||||
```dart
|
||||
supabase.from('countries')
|
||||
.stream(['id'])
|
||||
.stream(primaryKey: ['id'])
|
||||
.order('name', ascending: true)
|
||||
.listen((List<Map<String, dynamic>> data) {
|
||||
// Do something awesome with the data
|
||||
@@ -814,7 +795,7 @@ pages:
|
||||
dart: |
|
||||
```dart
|
||||
supabase.from('countries')
|
||||
.stream(['id'])
|
||||
.stream(primaryKey: ['id'])
|
||||
.order('name', ascending: true)
|
||||
.limit(10)
|
||||
.listen((List<Map<String, dynamic>> data) {
|
||||
@@ -837,7 +818,7 @@ pages:
|
||||
|
||||
class _MyWidgetState extends State<MyWidget> {
|
||||
// Persist the stream in a local variable to prevent refetching upon rebuilds
|
||||
final _stream = supabase.from('countries').stream(['id']);
|
||||
final _stream = supabase.from('countries').stream(primaryKey: ['id']);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
Reference in new issue
Block a user