Flutter集成Supabase重置密码:点击链接无法跳转至重置页面求助
解决方案:Flutter Supabase密码重置链接唤起App后跳转至重置页面
要解决点击重置邮件链接唤起App但无法跳转至ResetPassword页面的问题,需要完成深链接配置、App内链接监听与路由跳转、Supabase后台配置三个核心步骤,具体如下:
1. 配置iOS/Android深链接Scheme
确保App的Scheme与resetPasswordForEmail方法中redirectTo的Scheme一致(即io.supabase.bearincount):
iOS(Info.plist)
添加以下配置:
<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>io.supabase.bearincount</string> </array> </dict> </array>
Android(AndroidManifest.xml)
在MainActivity标签内添加Intent Filter:
<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="io.supabase.bearincount" /> </intent-filter>
2. Flutter内监听深链接并处理路由跳转
使用uni_links包监听App唤起时的深链接,解析重置token并导航至ResetPassword页面:
步骤1:添加依赖
在pubspec.yaml中添加:
dependencies: uni_links: ^0.5.1
步骤2:全局监听与路由处理
修改main.dart,添加深链接监听逻辑:
import 'package:flutter/material.dart'; import 'package:supabase_flutter/supabase_flutter.dart'; import 'package:uni_links/uni_links.dart'; // 全局导航键,用于跨上下文跳转 final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>(); void main() async { WidgetsFlutterBinding.ensureInitialized(); // 初始化Supabase await Supabase.initialize( url: '你的Supabase项目URL', anonKey: '你的Supabase匿名密钥', ); // 处理App启动时的初始深链接 final initialLink = await getInitialLink(); if (initialLink != null) { handleDeepLink(initialLink); } // 监听App运行中收到的深链接 linkStream.listen((link) { if (link != null) { handleDeepLink(link); } }); runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( navigatorKey: navigatorKey, initialRoute: '/login', routes: { '/login': (context) => const LoginView(), '/forgot-password': (context) => const ForgotPasswordPage(), '/reset-password': (context) => const ResetPassword(), }, ); } } // 解析深链接并跳转至重置页面 void handleDeepLink(String link) { final uri = Uri.parse(link); final token = uri.queryParameters['token']; final type = uri.queryParameters['type']; // 确认是密码重置类型的链接 if (type == 'recovery' && token != null) { navigatorKey.currentState?.pushNamed( '/reset-password', arguments: token, // 将重置token传递给页面 ); } }
步骤3:在ResetPassword页面使用token完成重置
修改ResetPassword页面,接收token并完成密码更新:
class ResetPassword extends StatelessWidget { const ResetPassword({super.key}); @override Widget build(BuildContext context) { final resetToken = ModalRoute.of(context)?.settings.arguments as String?; final newPasswordController = TextEditingController(); return Scaffold( appBar: AppBar(title: const Text('重置密码')), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ TextField( controller: newPasswordController, obscureText: true, decoration: const InputDecoration(labelText: '输入新密码'), ), const SizedBox(height: 16), ElevatedButton( onPressed: () async { if (resetToken == null || newPasswordController.text.isEmpty) return; try { // 使用重置token更新密码 await Supabase.instance.client.auth.updateUser( UserAttributes(password: newPasswordController.text), options: AuthOptions(token: resetToken), ); // 重置成功,跳转回登录页 navigatorKey.currentState?.pushReplacementNamed('/login'); } catch (e) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('重置失败:$e')), ); } }, child: const Text('确认重置'), ), ], ), ), ); } }
3. Supabase后台配置允许跳转链接
登录Supabase控制台,进入项目的Authentication > URL Configuration,将io.supabase.bearincount://reset-password/添加到Allowed Redirect URLs列表中,避免跳转被拦截。
验证要点
- 确保
resetPasswordForEmail方法中的redirectTo与配置的Scheme完全一致 - 测试邮件链接是否能正常唤起App,并自动跳转至重置页面
- 确认重置token能正确传递至
ResetPassword页面,完成密码更新
内容的提问来源于stack exchange,提问作者carloberd
相关产品推荐
相关产品推荐

