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

Flutter中Firestore已认证用户数据的获取与对象化处理问题

我帮你梳理下代码里的问题,然后给出修正后的版本,这样你就能轻松获取并展示当前认证用户的Firestore数据了:

核心问题梳理

你的代码里有几个关键问题导致无法正常获取用户数据:

  • 无效的内部方法定义、语法错误
  • 错误监听了整个集合的快照(没必要,应该只监听当前用户的文档)
  • DataService里的流方法与Personne的工厂方法不匹配
  • 没有正确使用Provider来获取和展示Personne对象

修正后的完整代码

import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:harcelementapp/authentification/controlAuth.dart';
import 'package:provider/provider.dart';

class Test extends StatefulWidget {
  @override
  _TestState createState() => _TestState();
}

class _TestState extends State<Test> {
  final DataService db = DataService();

  @override
  Widget build(BuildContext context) {
    // 获取当前已认证的用户
    final FirebaseUser? currentUser = Provider.of<FirebaseUser?>(context);

    // 处理未登录的情况
    if (currentUser == null) {
      return Scaffold(
        appBar: AppBar(title: const Text('Test')),
        body: const Center(child: Text('请先登录')),
      );
    }

    return Scaffold(
      appBar: AppBar(title: const Text('Test')),
      // 通过StreamProvider提供当前用户的Firestore数据
      body: StreamProvider<Personne?>.value(
        initialData: null,
        value: db.streamPersonne(currentUser.uid),
        child: const UserInfoDisplay(),
      ),
    );
  }
}

// 单独拆分的组件,负责显示用户信息,解耦代码
class UserInfoDisplay extends StatelessWidget {
  const UserInfoDisplay({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // 获取Provider提供的用户数据
    final Personne? userData = Provider.of<Personne?>(context);

    // 处理数据加载中的状态
    if (userData == null) {
      return const Center(child: Text('加载中...'));
    }

    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      crossAxisAlignment: CrossAxisAlignment.center,
      children: [
        Text('用户名: ${userData.nom}'),
        const SizedBox(height: 16),
        Text('邮箱: ${userData.mail}'),
        const SizedBox(height: 16),
        Text('角色: ${userData.role}'),
        const SizedBox(height: 16),
        Text('电话: ${userData.tel}'),
      ],
    );
  }
}

class Personne {
  final String userId;
  final String nom;
  final String mail;
  final String tel;
  final String role;

  Personne({
    required this.userId,
    required this.nom,
    required this.mail,
    required this.tel,
    required this.role,
  });

  // 修正工厂方法,正确从Firestore文档转换为Personne对象
  factory Personne.fromFirestore(DocumentSnapshot doc) {
    final data = doc.data() as Map<String, dynamic>;
    // 添加空值处理,避免字段缺失导致崩溃
    return Personne(
      userId: doc.id,
      nom: data['nomComplet'] ?? '未知用户名',
      mail: data['emailUtil'] ?? '未知邮箱',
      tel: data['numeroTel'] ?? '未知电话',
      role: data['userRole'] ?? '未知角色',
    );
  }
}

class DataService {
  final Firestore _db = Firestore.instance;

  // 修正流方法,只监听当前用户的单个文档
  Stream<Personne?> streamPersonne(String userId) {
    return _db
        .collection('utilisateurs')
        .document(userId)
        .snapshots()
        .map((snap) {
      // 如果文档不存在,返回null
      if (!snap.exists) return null;
      return Personne.fromFirestore(snap);
    });
  }
}

关键改进说明

  1. 用户状态校验:先判断当前用户是否登录,避免未登录状态下的无效操作
  2. 高效数据流:只监听当前用户的单个Firestore文档,而非整个集合,减少资源消耗
  3. 空值安全:在Personne的工厂方法中添加空值兜底,避免Firestore字段缺失导致应用崩溃
  4. 组件解耦:把用户信息显示拆分为独立组件,代码结构更清晰,符合单一职责原则
  5. 正确使用Provider:通过StreamProvider提供响应式的用户数据,子组件可以实时获取数据更新

内容的提问来源于stack exchange,提问作者sydney thomas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 16:47:43