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

如何解决Flutter中从Firebase Firestore显示当前用户信息为空的问题?

Flutter Firestore 个人资料页姓名显示为空问题排查与解决

问题描述

在Flutter项目中使用Firebase Firestore数据库,集合名为users,期望用户登录后在个人资料页面显示姓名、邮箱等信息,但运行时姓名显示为空。相关代码如下:

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:gtu_all_in_one/Pages/FirstPage.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:provider/provider.dart';

import '../Providers/SignInProvider.dart';
import '../Utils/NextScreen.dart';

import '../models/QrCodeScannerPage.dart';

class ProfilePage extends StatefulWidget {
  const ProfilePage({Key? key}) : super(key: key);

  @override
  State<ProfilePage> createState() => _ProfilePageState();
}

class _ProfilePageState extends State<ProfilePage> {
  String? name = " ";
  String? email;

  final currentUser = FirebaseAuth.instance;

  Future _getDataFromDatabase() async {
    await FirebaseFirestore.instance
        .collection('users')
        .doc(FirebaseAuth.instance.currentUser!.uid)
        .get()
        .then((snapshot) async {
      if (snapshot.exists) {
        setState(() {
          name = snapshot.data()!["name"];
          email = snapshot.data()!["Email"];
        });
      }
    });
  }

  @override
  void initState() {
    super.initState();
    _getDataFromDatabase();
  }

  @override
  Widget build(BuildContext context) {
    final sp = context.watch<SignInProvider>();

    return SafeArea(
      child: Scaffold(
        resizeToAvoidBottomInset: false,
        body: Center(
          child: Column(
            children: [
              SizedBox(height: 300),

              Text("Name is : $name"),

              SizedBox(height: 10),

              Container(
                height: 40,
                width: 70,
                color: Colors.greenAccent,
                child: TextButton(
                  onPressed: () {
                    print("name is :" + name.toString());
                  },
                  child: Text("Btn"),
                ),
              ),

              SizedBox(height: 10),

              SizedBox(
                height: 50,
                width: 250,
                child: ElevatedButton(
                  style: ElevatedButton.styleFrom(
                    primary: HexColor("#48EDC5"),
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(22),
                    ),
                  ),

                  child: Row(
                    children: [
                      Container(
                        margin: const EdgeInsets.only(left: 13),
                        child: Text(
                          "Mark Attendance",
                          style: TextStyle(
                              fontFamily: 'Gotham',
                              color: HexColor("#002C00"),
                              fontSize: 20),
                        ),
                      ),

                      Container(
                        margin: EdgeInsets.only(left: 5),
                        child: Icon(
                          Icons.qr_code_scanner,
                          size: 22,
                          color: HexColor("#002C00"),
                        ),
                      ),
                    ],
                  ),

                  onPressed: () {
                    nextScreen(context, QRCodeScanner());
                  },
                ),
              ),

              SizedBox(height: 10),

              SizedBox(
                height: 50,
                width: 150,
                child: ElevatedButton(
                  style: ElevatedButton.styleFrom(
                    primary: HexColor("#48EDC5"),
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(22),
                    ),
                  ),

                  child: Row(
                    children: [
                      Container(
                        margin: const EdgeInsets.only(left: 13),
                        child: Text(
                          "log Out",
                          style: TextStyle(
                              fontFamily: 'Gotham',
                              color: HexColor("#002C00"),
                              fontSize: 20),
                        ),
                      ),

                      Container(
                        margin: EdgeInsets.only(left: 5),
                        child: Icon(
                          Icons.arrow_forward_ios,
                          size: 22,
                          color: HexColor("#002C00"),
                        ),
                      ),
                    ],
                  ),

                  onPressed: () {
                    sp.userSignOut();
                    nextScreenReplace(context, FirstPage());
                  },
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

核心排查点与解决步骤

1. 字段名大小写匹配问题

Firestore字段名大小写敏感,检查Firestore控制台中users集合的用户文档:

  • 确认姓名字段是name(代码中使用的键),而非Name/NAME等其他形式
  • 邮箱字段同理,代码中用Email,需确保数据库中字段名完全一致

2. 用户文档存在性验证

在Firestore控制台通过当前用户UID搜索对应文档:

  • 确认文档已创建,且name字段有非空值
  • 若文档不存在,检查用户注册逻辑,确保注册时已向users集合写入用户数据

3. Firestore安全规则配置

确保已配置允许已登录用户读取自己的文档,示例规则:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
  }
}

4. 异步加载逻辑优化

修改代码,增加加载状态提示与异常捕获,避免空值显示与排查困难:

class _ProfilePageState extends State<ProfilePage> {
  String? name = " ";
  String? email;
  bool isLoading = true; // 加载状态标记

  Future _getDataFromDatabase() async {
    try {
      final user = FirebaseAuth.instance.currentUser;
      if (user == null) {
        setState(() => isLoading = false);
        return;
      }
      final snapshot = await FirebaseFirestore.instance
          .collection('users')
          .doc(user.uid)
          .get();
      
      if (snapshot.exists) {
        setState(() {
          name = snapshot.data()!["name"] ?? "未设置姓名"; // 空值兜底
          email = snapshot.data()!["Email"] ?? "未设置邮箱";
          isLoading = false;
        });
      } else {
        setState(() {
          name = "用户文档不存在";
          isLoading = false;
        });
      }
    } catch (e) {
      setState(() {
        name = "加载失败: ${e.toString()}";
        isLoading = false;
      });
      print("获取用户数据失败: $e");
    }
  }

  @override
  Widget build(BuildContext context) {
    final sp = context.watch<SignInProvider>();

    return SafeArea(
      child: Scaffold(
        resizeToAvoidBottomInset: false,
        body: Center(
          child: isLoading 
              ? CircularProgressIndicator() // 加载中显示指示器
              : Column(
            children: [
              // 原有页面内容
            ],
          ),
        ),
      ),
    );
  }
}

内容的提问来源于stack exchange,提问作者Dhruv Mavani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 17:01:22