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), ), ], ), ), ); }, ), ), ); } }
额外注意事项
- 字段名匹配:确保Firestore中
Users集合的文档字段名和代码中使用的完全一致(比如Firstname是否大写开头、Registration Date是否带空格),Firestore字段名区分大小写且严格匹配。 - 文档ID自定义场景:若用户文档不是用UID作为文档ID,而是用自定义
id字段存储UID,需把stream部分改成:
同时将stream: _firestore.collection('Users').where("id", isEqualTo: currentUser.uid).snapshots(),StreamBuilder<DocumentSnapshot>改回StreamBuilder<QuerySnapshot>,并取查询结果的第一个文档(查询只会返回一个结果)。 - 安全规则配置:确保Firestore安全规则允许已登录用户读取自己的文档,示例规则:
match /Users/{userId} { allow read, write: if request.auth != null && request.auth.uid == userId; }
内容的提问来源于stack exchange,提问作者erastus developer
相关产品推荐
相关产品推荐

