Flutter+Firebase应用点击Profile导航图标崩溃及Firestore不可用问题
解决Flutter+Firebase应用点击Profile页面冻结及Firestore不可用错误
问题分析
点击底部导航栏Profile图标时应用冻结,伴随错误[cloud_firestore/unavailable] The service is currently unavailable,结合代码排查,核心问题包括:
- Profile页面的FutureBuilder未正确处理快照数据、加载状态和错误情况
- UserModel的fromMap方法存在语法错误
- 底部导航栏提前初始化页面,可能导致Firestore请求触发时机异常
- 未处理Firestore请求失败场景,导致应用陷入无限等待
修复步骤
1. 修正Profile页面的FutureBuilder逻辑
原代码直接使用Map类型而非快照数据,且缺失状态处理,修改后代码如下:
Widget buildProfileHeader() { return FutureBuilder<DocumentSnapshot>( future: userRef.doc(widget.userProfile).get(), builder: (context, snapshot) { // 处理加载中状态 if (snapshot.connectionState == ConnectionState.waiting) { return const CircularProgressIndicator(); } // 处理错误状态 if (snapshot.hasError) { return Center( child: Text('加载失败: ${snapshot.error}'), ); } // 处理无数据状态 if (!snapshot.hasData || snapshot.data!.data() == null) { return const Center(child: Text('用户数据不存在')); } // 正确解析用户数据 UserModel user = UserModel.fromMap(snapshot.data!.data() as Map<String, dynamic>); return Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ const Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(Icons.account_circle, size: 90,) ], ), Container( alignment: Alignment.center, padding: const EdgeInsets.all(12.0), child: Text( user.Username ?? '匿名用户', style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 16.0, ), ), ), ], ), ); }, ); }
同时在build方法中取消注释,添加该组件:
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( centerTitle: true, title: const Text("Profile"), ), body: ListView( children: [buildProfileHeader()], ), ); }
2. 修复UserModel的fromMap方法
原方法参数无类型且命名不规范,修正后:
import 'package:flutter/foundation.dart'; class UserModel { String? uid; String? Username; String? email; String? photoUrl; UserModel({this.uid, this.email, this.Username, this.photoUrl}); // 从Firestore映射转换为UserModel factory UserModel.fromMap(Map<String, dynamic> map) { return UserModel( uid: map['userId'], Username: map['Username'], email: map['email'], photoUrl: map['photoUrl'], ); } // 转换为Firestore映射 Map<String, dynamic> toMap() { return { 'userId': uid, 'Username': Username, 'email': email, 'photoUrl': photoUrl, }; } }
3. 调整底部导航栏页面初始化逻辑
原代码提前初始化所有页面,可能导致Firestore请求在用户未完全登录时触发,改为动态构建页面:
class _BottomBarState extends State<BottomBar> { int currentIndex = 0; void onTap(int index) { setState(() { currentIndex = index; }); } // 动态构建当前页面 Widget _buildCurrentPage() { switch(currentIndex) { case 0: return const home_page(); case 1: return const search(); case 2: return const upload(); case 3: final userId = FirebaseAuth.instance.currentUser?.uid; if(userId == null) { return const Center(child: Text('请先登录')); } return profile(userProfile: userId); default: return const home_page(); } } @override Widget build(BuildContext context) { return Scaffold( body: _buildCurrentPage(), bottomNavigationBar: BottomNavigationBar( type: BottomNavigationBarType.fixed, selectedFontSize: 0, unselectedFontSize: 0, onTap: onTap, currentIndex: currentIndex, backgroundColor: Colors.white, selectedItemColor: Colors.black87, unselectedItemColor: Colors.grey.shade600.withOpacity(0.6), elevation: 0, items: const [ BottomNavigationBarItem( icon: Icon(Icons.home_outlined), label: 'home'), BottomNavigationBarItem(icon: Icon(Icons.search), label: 'search'), BottomNavigationBarItem( icon: Icon(Icons.add_box_outlined), label: 'add'), BottomNavigationBarItem( icon: Icon(Icons.person_outline_rounded), label: 'profile'), ], ), ); } }
4. 基础配置检查
- 确认Android的
google-services.json、iOS的GoogleService-Info.plist已正确放置在对应目录 - 检查设备/模拟器网络连接正常
- 验证Firebase控制台中Firestore服务已启用,测试阶段可临时将安全规则设置为
allow read, write: if true;(上线后需调整为安全规则)
额外优化建议
- 在main函数中初始化Firebase:
await Firebase.initializeApp(); - 监听Auth状态变化,避免未登录场景崩溃:
FirebaseAuth.instance.authStateChanges().listen((user) { // 根据登录状态更新UI });
内容的提问来源于stack exchange,提问作者Abderrezak Douba
相关产品推荐
相关产品推荐

