You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:07:48