如何在Flutter的CategorySelector中获取Firebase当前用户信息并展示
解决Firestore用户信息获取与展示问题
我来帮你一步步实现在CategorySelector组件中展示登录用户的头像和用户名。咱们从完善现有代码、添加数据获取逻辑到最终UI展示来梳理:
1. 完善数据库操作类,添加用户数据获取方法
首先你的DatabaseManager只实现了创建用户数据的方法,需要新增一个通过用户ID获取数据的方法:
class DatabaseManager { final CollectionReference users = FirebaseFirestore.instance.collection('users'); Future<void> createUserData( String email, String imageUrl, String uid) async { return await users.doc(uid).set({ 'id': uid, 'email': email, 'user_name': email.substring(0, email.lastIndexOf("@")), 'img_url': imageUrl }); } // 新增:通过uid获取用户完整数据 Future<UserModel> getUserData(String uid) async { try { DocumentSnapshot doc = await users.doc(uid).get(); if (doc.exists) { return UserModel.fromMap(doc.data() as Map<String, dynamic>); } return null; } catch (e) { print('获取用户数据失败: ${e.toString()}'); return null; } } }
2. 修复User模型的类型匹配问题
注意你Firestore中存储的id是字符串类型的UID,所以需要调整模型类的字段类型,同时修正字段映射:
import 'package:flutter/foundation.dart'; // 改名UserModel避免和Firebase的User类冲突 class UserModel { String id; // 改为String类型,对应Firestore中的uid String name; String email; String imageUrl; UserModel({ @required this.id, @required this.name, @required this.imageUrl, @required this.email, }); UserModel.fromMap(Map<String, dynamic> json) { this.id = json['id']; this.name = json['user_name']; // 对应Firestore中的user_name字段 this.imageUrl = json['img_url']; this.email = json['email']; // 密码不要存Firestore,这里也不需要读取 } }
3. 修改CategorySelector组件,实现数据获取与展示
我们使用FutureBuilder来处理异步数据加载,先获取当前登录用户的Auth信息,再通过UID从Firestore拉取完整用户数据,最后加载头像并展示:
class CategorySelector extends StatefulWidget { @override _CategorySelectorState createState() => _CategorySelectorState(); } class _CategorySelectorState extends State<CategorySelector> { final AuthenticationService _authService = AuthenticationService(); final DatabaseManager _dbManager = DatabaseManager(); // 获取当前登录用户的完整数据(Auth + Firestore) Future<UserModel> _getCurrentUserData() async { User authUser = await _authService.getCurrentUser(); if (authUser != null) { return await _dbManager.getUserData(authUser.uid); } return null; } // 从Firebase Storage加载用户头像 Future<Image> _loadUserAvatar(String imagePath) async { String downloadUrl = await FirebaseStorage.instance.ref().child(imagePath).getDownloadURL(); return Image.network(downloadUrl, fit: BoxFit.cover); } @override Widget build(BuildContext context) { return Container( height: 100.0, width: double.infinity, child: FutureBuilder<UserModel>( future: _getCurrentUserData(), builder: (context, snapshot) { // 加载中状态 if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } // 加载错误状态 else if (snapshot.hasError) { return const Center(child: Text('加载用户信息失败')); } // 未登录或无数据状态 else if (!snapshot.hasData || snapshot.data == null) { return const Center(child: Text('请先登录')); } // 成功获取数据,展示UI else { UserModel user = snapshot.data!; return Row( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: <Widget>[ // 用户头像 Container( width: 80.0, height: 80.0, margin: const EdgeInsets.only(left: 10.0), decoration: BoxDecoration( borderRadius: BorderRadius.circular(20.0), boxShadow: const [ BoxShadow( color: Colors.black12, blurRadius: 5.0, offset: Offset(8, 8) ) ] ), child: ClipRRect( borderRadius: BorderRadius.circular(20.0), child: FutureBuilder<Image>( future: _loadUserAvatar(user.imageUrl), builder: (context, imgSnapshot) { if (imgSnapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); } else if (imgSnapshot.hasError) { // 加载失败时显示默认头像 return Image.asset('assets/default_avatar.png'); } else { return imgSnapshot.data!; } }, ), ), ), // 欢迎文本与用户名 Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ const Text('Welcome,', style: TextStyle( fontFamily: 'Roboto', color: Colors.grey, fontSize: 20.0, ),), Text(user.name, style: const TextStyle( fontFamily: 'Roboto', color: Colors.black54, fontSize: 20.0, fontWeight: FontWeight.bold, ),), ], ), // 右侧Logo Container( margin: const EdgeInsets.only(right: 10.0), width: 80.0, height: 80.0, child: Image.asset('assets/images/logo.png'), ), ], ); } }, ), ); } }
关键注意事项
- 状态持久化:Firebase Auth默认会持久化用户登录状态,重启APP后
_auth.currentUser依然能获取到当前用户。 - 实时更新:如果需要监听用户数据的实时变化(比如用户修改头像),可以把外层的
FutureBuilder换成StreamBuilder,监听Firestore文档的实时更新。 - 安全优化:永远不要把用户密码存储到Firestore中,Firebase Auth已经负责密码的安全管理。
- 错误处理:代码中添加了加载失败的 fallback 逻辑,你可以根据需求替换默认头像或提示文本。
内容的提问来源于stack exchange,提问作者prabin maharjan
相关产品推荐
相关产品推荐

