Flutter跳转至欢迎页时如何获取并传递UserCredential
解决方案
方案1:登录/注册成功后直接跳转并传递UserCredential
这种方式最简单,不需要额外状态管理,适合大部分场景。
在登录页的signIn方法中,获取UserCredential后直接跳转到WelcomePage并传入参数:
Future<void> signIn(String email, String password) async { try { final userCredential = await FirebaseAuth.instance .signInWithEmailAndPassword(email: email, password: password); // 登录成功后跳转并传参 if (userCredential.user != null) { Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => WelcomePage(userCredential: userCredential), ), ); } } on FirebaseAuthException catch (e) { // 处理错误 print(e.message); } }
注册页的signUp方法同理:
Future<void> signUp(String email, String password) async { try { final userCredential = await FirebaseAuth.instance .createUserWithEmailAndPassword(email: email, password: password); // 注册成功后跳转并传参 if (userCredential.user != null) { Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => WelcomePage(userCredential: userCredential), ), ); } } on FirebaseAuthException catch (e) { // 处理错误 print(e.message); } }
MainPage的StreamBuilder只需要处理未登录状态和持久化登录的情况:
class MainPage extends StatelessWidget { @override Widget build(BuildContext context) { return StreamBuilder<User?>( stream: FirebaseAuth.instance.authStateChanges(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const CircularProgressIndicator(); } // 用户已登录(包括持久化登录) else if (snapshot.hasData && snapshot.data != null) { // 持久化登录时没有UserCredential,可通过User构造一个基础的Credential return WelcomePage( userCredential: UserCredential( auth: FirebaseAuth.instance, user: snapshot.data, ), ); } // 用户未登录 else { return LoginPage(); } }, ); } }
WelcomePage接收参数:
class WelcomePage extends StatelessWidget { final UserCredential userCredential; const WelcomePage({super.key, required this.userCredential}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Welcome')), body: Center( child: Text('Hello, ${userCredential.user?.email}!'), ), ); } }
方案2:使用状态管理存储UserCredential(适合复杂场景)
如果你的应用需要在多个页面访问UserCredential,或者要处理更复杂的状态逻辑,可以用状态管理库(比如Provider)来存储。
步骤1:创建Auth状态管理类
import 'package:flutter/material.dart'; import 'package:firebase_auth/firebase_auth.dart'; class AuthProvider extends ChangeNotifier { UserCredential? _userCredential; UserCredential? get userCredential => _userCredential; // 设置UserCredential并通知监听者 void setUserCredential(UserCredential credential) { _userCredential = credential; notifyListeners(); } // 清除UserCredential(退出登录时调用) void clearUserCredential() { _userCredential = null; notifyListeners(); } }
步骤2:在应用入口初始化Provider
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; void main() { runApp( ChangeNotifierProvider( create: (context) => AuthProvider(), child: const MyApp(), ), ); }
步骤3:登录/注册时更新状态
登录页的signIn方法:
Future<void> signIn(String email, String password, BuildContext context) async { try { final userCredential = await FirebaseAuth.instance .signInWithEmailAndPassword(email: email, password: password); // 更新Provider中的UserCredential Provider.of<AuthProvider>(context, listen: false) .setUserCredential(userCredential); Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => const WelcomePage()), ); } on FirebaseAuthException catch (e) { print(e.message); } }
注册页的signUp方法同理。
步骤4:在WelcomePage中获取状态
class WelcomePage extends StatelessWidget { const WelcomePage({super.key}); @override Widget build(BuildContext context) { final userCredential = Provider.of<AuthProvider>(context).userCredential; return Scaffold( appBar: AppBar(title: const Text('Welcome')), body: Center( child: Text('Hello, ${userCredential?.user?.email}!'), ), ); } }
步骤5:MainPage处理状态
class MainPage extends StatelessWidget { @override Widget build(BuildContext context) { return StreamBuilder<User?>( stream: FirebaseAuth.instance.authStateChanges(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const CircularProgressIndicator(); } else if (snapshot.hasData && snapshot.data != null) { return const WelcomePage(); } else { // 退出登录时清除状态 Provider.of<AuthProvider>(context, listen: false).clearUserCredential(); return LoginPage(); } }, ); } }
注意事项
- 如果
WelcomePage只需要用户的基础信息(如邮箱、UID),可以直接传递User对象(从authStateChanges或userCredential.user获取),无需传递完整的UserCredential。 - 持久化登录场景下,
authStateChanges只会返回User对象,此时如果必须使用UserCredential,可以通过User构造一个基础实例(如方案1中的写法),或者在状态管理中判断是否存在缓存的UserCredential。
内容的提问来源于stack exchange,提问作者Irfan Ganatra
相关产品推荐
相关产品推荐

