Flutter中Firestore获取role字段触发Bad state异常问题排查
问题描述
我在Firestore中创建了Users集合,每个文档包含name、email、password、phone、role字段,想通过获取role字段实现Flutter应用中普通用户和管理员跳转至不同仪表盘的功能,但运行代码时抛出异常:
Exception has occurred. StateError (Bad state: cannot get a field on a DocumentSnapshotPlatform which does not exist)
Firestore数据库说明:Users集合下的文档以用户UID为文档ID,每个文档包含上述5个字段,role字段值为user或admin。
相关代码:
import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:role_base_app/Views/admin_dashboard.dart'; import 'package:role_base_app/Views/user_dashboard.dart'; class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { return SafeArea( child: Scaffold( appBar: AppBar( title: const Text("Home"), ), body: StreamBuilder<User?>( stream: FirebaseAuth.instance.authStateChanges(), builder: (context, snapshot) { if (snapshot.hasData && snapshot.data != null) { return StreamBuilder( stream: FirebaseFirestore.instance .collection("Users") .doc(snapshot.data!.uid) .snapshots(), builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) { if (snapshot.hasData && snapshot.data != null) { final user = snapshot.data!; // devtools.log(user.toString()); if (user['role'] == 'user') { return const UserDashboard(); } else { return const AdminDashboard(); } } return const Text("Done"); }, ); } return const Text("well Done"); }, ), ), ); } }
解决方案
检查文档与字段的正确性
确认Users集合下,当前登录用户UID对应的文档确实存在,且role字段拼写完全一致(Firestore字段名大小写敏感,别写成Role或ROLE)。可以在代码中临时添加print(user.data());打印文档所有字段,确认role是否存在。安全访问字段,避免直接下标取值
直接用user['role']会在字段不存在时抛出异常,改用安全取值方式:final userData = user.data() as Map<String, dynamic>; final role = userData['role']; // 或者用user.get('role', defaultValue: null) if (role == 'user') { return const UserDashboard(); } else if (role == 'admin') { return const AdminDashboard(); } else { // 处理角色不存在或未知的情况 return const Text('用户角色未设置,请联系管理员'); }验证Firestore权限规则
确保当前用户有权限读取自己的文档,在Firebase控制台的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; } } }完善快照状态处理
原代码未处理加载状态和错误情况,补充后避免过早访问数据:builder: (BuildContext context, AsyncSnapshot<DocumentSnapshot> snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const CircularProgressIndicator(); } if (snapshot.hasError) { return Text('加载失败: ${snapshot.error}'); } // 确认文档存在 if (!snapshot.hasData || !snapshot.data!.exists) { return const Text('未找到用户信息,请完善资料'); } final userData = snapshot.data!.data() as Map<String, dynamic>; final role = userData['role']; if (role == 'user') { return const UserDashboard(); } else if (role == 'admin') { return const AdminDashboard(); } else { return const Text('未知用户角色'); } },
内容的提问来源于stack exchange,提问作者Francis Annor
相关产品推荐
相关产品推荐

