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

Flutter中获取当前登录用户Firestore数据失败求助

解决Flutter从Firebase Firestore获取当前用户数据的问题

核心问题分析

你的代码无法获取数据,大概率是以下几个原因:

  • 查询方式错误:若用户文档的文档ID就是用户UID(Firestore存储用户数据的常规做法),用where("id", isEqualTo: uid)的集合查询完全没必要,直接通过文档ID获取单个文档更高效且不易出错;如果是自定义字段存储UID,要确保字段名完全匹配(Firestore字段名区分大小写)。
  • StreamBuilder类型错误:你用StreamBuilder<QuerySnapshot>处理单用户数据,实际上单个用户对应单个文档,应该用StreamBuilder<DocumentSnapshot>。
  • 空安全与未登录处理:直接使用FirebaseAuth.instance.currentUser!.uid会在用户未登录时崩溃,必须先判断用户登录状态。
  • 布局嵌套问题:SingleChildScrollView嵌套ListView+全屏高度容器,会导致布局溢出,且完全没必要。

修正后的代码

import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:lostfound/Authentication/reusableWidgets1.dart';

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

  @override
  State<Profile> createState() => _ProfileState();
}

class _ProfileState extends State<Profile> {
  final FirebaseAuth _auth = FirebaseAuth.instance;
  final FirebaseFirestore _firestore = FirebaseFirestore.instance;

  @override
  Widget build(BuildContext context) {
    final User? currentUser = _auth.currentUser;
    
    // 先判断用户是否登录
    if (currentUser == null) {
      return const Scaffold(
        body: Center(child: Text("请先登录")),
      );
    }

    return Scaffold(
      appBar: AppBar(
        title: const Text("用户资料"),
        centerTitle: true,
      ),
      body: SingleChildScrollView(
        padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 40),
        child: StreamBuilder<DocumentSnapshot>(
          // 直接通过用户UID获取文档(假设文档ID=用户UID)
          stream: _firestore.collection('Users').doc(currentUser.uid).snapshots(),
          builder: (context, snapshot) {
            if (snapshot.hasError) {
              return const Center(child: Text("加载出错,请稍后重试"));
            }

            if (snapshot.connectionState == ConnectionState.waiting) {
              return const Center(
                child: CircularProgressIndicator(color: Colors.red),
              );
            }

            // 判断文档是否存在
            if (!snapshot.data!.exists) {
              return const Center(child: Text("用户资料不存在"));
            }

            final userData = snapshot.data!.data() as Map<String, dynamic>;

            return Card(
              shape: RoundedRectangleBorder(
                borderRadius: BorderRadius.circular(30),
              ),
              child: Container(
                padding: const EdgeInsets.all(20),
                decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(30),
                  gradient: LinearGradient(
                    begin: Alignment.bottomLeft,
                    end: Alignment.topRight,
                    colors: [
                      Colors.green.withOpacity(1.0),
                      Colors.greenAccent.withOpacity(1.0),
                    ],
                  ),
                ),
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    // 头像处理:添加错误占位符
                    Center(
                      child: Container(
                        height: 150,
                        width: double.infinity,
                        decoration: BoxDecoration(
                          borderRadius: BorderRadius.circular(20),
                          color: Colors.white10,
                        ),
                        child: userData['Image'] != null
                            ? Image.network(
                                userData['Image'],
                                fit: BoxFit.fitWidth,
                                errorBuilder: (context, error, stackTrace) {
                                  return const Icon(Icons.person, size: 80, color: Colors.white70);
                                },
                              )
                            : const Icon(Icons.person, size: 80, color: Colors.white70),
                      ),
                    ),
                    const SizedBox(height: 16), // 替代自定义的Space(),若Space是自定义组件可保留
                    Text(
                      userData['Firstname'] ?? "未设置",
                      style: const TextStyle(color: Colors.white70, fontSize: 20),
                    ),
                    const SizedBox(height: 16),
                    Text(
                      userData['Lastname'] ?? "未设置",
                      style: const TextStyle(color: Colors.white70, fontSize: 20),
                    ),
                    const SizedBox(height: 16),
                    Text(
                      userData['Email'] ?? "未设置",
                      style: const TextStyle(color: Colors.white70, fontSize: 20),
                    ),
                    const SizedBox(height: 16),
                    Text(
                      userData['PhoneNumber'] ?? "未设置",
                      style: const TextStyle(color: Colors.white70, fontSize: 20),
                    ),
                    const SizedBox(height: 16),
                    Text(
                      userData['Registration Date'] ?? "未设置",
                      style: const TextStyle(color: Colors.white70, fontSize: 20),
                    ),
                  ],
                ),
              ),
            );
          },
        ),
      ),
    );
  }
}

额外注意事项

  1. 字段名匹配:确保Firestore中Users集合的文档字段名和代码中使用的完全一致(比如Firstname是否大写开头、Registration Date是否带空格),Firestore字段名区分大小写且严格匹配。
  2. 文档ID自定义场景:若用户文档不是用UID作为文档ID,而是用自定义id字段存储UID,需把stream部分改成:
    stream: _firestore.collection('Users').where("id", isEqualTo: currentUser.uid).snapshots(),
    
    同时将StreamBuilder<DocumentSnapshot>改回StreamBuilder<QuerySnapshot>,并取查询结果的第一个文档(查询只会返回一个结果)。
  3. 安全规则配置:确保Firestore安全规则允许已登录用户读取自己的文档,示例规则:
    match /Users/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
    

内容的提问来源于stack exchange,提问作者erastus developer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 08:54:59