diff --git a/packages/console/src/assets/docs/guides/native-flutter/README.mdx b/packages/console/src/assets/docs/guides/native-flutter/README.mdx index 870d26680..c192872ef 100644 --- a/packages/console/src/assets/docs/guides/native-flutter/README.mdx +++ b/packages/console/src/assets/docs/guides/native-flutter/README.mdx @@ -8,14 +8,35 @@ import InlineNotification from '@/ds-components/InlineNotification'; -Our flutter SDK package is published on [pub.dev](https://pub.dev/packages/logto_dart_sdk). Install the SDK package by running the following command in your project directory: + -```bash -flutter pub get logto_dart_sdk + + +You can install the `logto_dart_sdk package` directly using the pub package manager. +Run the following command under your project root: + +```sh + flutter pub get logto_dart_sdk ``` + + + + +If you prefer to fork your own version of the SDK, you can clone the repository directly from GitHub. + +```sh + git clone https://github.com/logto-io/dart +``` + + + + + + +
flutter_secure_storage @@ -43,13 +64,14 @@ android { } ``` +### Disable autobackup: + - -By default Android backups data on Google Drive. It can cause exception `java.security.InvalidKeyException:Failed` to unwrap key. You will need to: - -- Disable `autobackup`; -- Exclude `sharedprefs` FlutterSecureStorage used by the plugin; - + By default Android backups data on Google Drive. It can cause exception + `java.security.InvalidKeyException:Failed` to unwrap key. +
+ You will need to either disable `autobackup` or exclude `sharedprefs` used by the + FlutterSecureStorage plugin.
1. To disable `autobackup`, go to your app manifest file and set the boolean value `android:allowBackup`: @@ -68,7 +90,7 @@ By default Android backups data on Google Drive. It can cause exception `java.se ``` -2. Exclude `sharedprefs` FlutterSecureStorage. +2. To exclude `sharedprefs` for FlutterSecureStorage. If you need to enable the `android:fullBackupContent` for your app. Set up a backup rule to [exclude](https://developer.android.com/guide/topics/data/autobackup#IncludingFiles) the prefs used by the plugin: @@ -127,8 +149,11 @@ In order to capture the callback url from Logto's sign-in web page, you will nee
+ +Import the `logto_dart_sdk` package and initialize the `LogtoClient` instance at the root of your application. +
   
     {`
@@ -139,8 +164,8 @@ late LogtoClient logtoClient;
 
 // LogtoConfig
 final logtoConfig = const LogtoConfig(
-  endpoint: '${props.endpoint}',
-  appId: '${props.app.id}',
+  endpoint: '${props.endpoint}', // Your Logto endpoint
+  appId: '${props.app.id}', // Your App ID
 );
 
 void init() async {
@@ -181,7 +206,7 @@ Let's switch to the Application details page of Logto Admin Console. Add a Redir
 
 
 
-Calling `.signOut()` will clean all the Logto data in the secret storage, if it has.
+### Implement a sign-out method
 
 ```dart
 void signOut() async {
@@ -189,6 +214,125 @@ void signOut() async {
 }
 ```
 
+
+  The `signOut` method will clear the user's session and remove the token from the secure storage.
+
+
+
+
+
+
+In Logto SDK, you can use `logtoClient.isAuthenticated` to check the authentication status, if the
+user is signed in, the value will be `true`, otherwise, the value will be `false`.
+
+```dart
+ bool isAuthenticated = await logtoClient.isAuthenticated;
+```
+
+
+
+
+
+Now let's wrap up the implementation and test your application.
+
+
+  
+    {`import 'package:logto_dart_sdk/logto_dart_sdk.dart';
+import 'package:http/http.dart' as http;
+
+void main() {
+  runApp(const MyApp());
+}
+
+class MyApp extends StatelessWidget {
+  const MyApp({Key? key}) : super(key: key);
+
+  @override
+  Widget build(BuildContext context) {
+    return const MaterialApp(
+      title: 'Flutter Demo',
+      home: MyHomePage(title: 'Logto Demo Home Page'),
+    );
+  }
+}
+
+class MyHomePage extends StatefulWidget {
+  const MyHomePage({Key? key, required this.title}) : super(key: key);
+  final String title;
+
+  @override
+  State createState() => _MyHomePageState();
+}
+
+class _MyHomePageState extends State {
+  late LogtoClient logtoClient;
+  bool? isAuthenticated = false;
+
+  // Update the authentication state
+  void render() {
+    setState(() async {
+      isAuthenticated = await logtoClient.isAuthenticated;
+    });
+  }
+
+  // LogtoConfig
+  final logtoConfig = const LogtoConfig(
+    endpoint: '${props.endpoint}',
+    appId: '${props.app.id}',
+  );
+
+  void _init() {
+    logtoClient = LogtoClient(
+      config: logtoConfig,
+      httpClient: http.Client(), // Optional http client
+    );
+    render();
+  }
+
+  @override
+  void initState() {
+    super.initState();
+    _init();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    Widget signInButton = TextButton(
+      onPressed: () async {
+        await logtoClient.signIn('${props.redirectUris[0] ?? 'io.logto://callback'}');
+        render();
+      },
+      child: const Text('Sign In'),
+    );
+
+    Widget signOutButton = TextButton(
+      onPressed: () async {
+        await logtoClient.signOut();
+        render();
+      },
+      child: const Text('Sign Out'),
+    );
+
+    return Scaffold(
+      appBar: AppBar(
+        title: Text(widget.title),
+      ),
+      body: Center(
+        child: Column(
+          mainAxisAlignment: MainAxisAlignment.center,
+          children: [
+            SelectableText('My Demo App'),
+            isAuthenticated ? signOutButton : signInButton,
+          ],
+        ),
+      ),
+    );
+  }
+}
+`}
+  
+
+