如何修复Firestore报错:期望DatabaseUser类型但得到_JsonQuery
问题:读取Firestore数据时报类型匹配错误
运行时抛出的错误信息如下:
Error: Expected a value of type 'DatabaseUser$', but got one of type '_JsonQuery'
场景说明
需求为用户登录后,从Firestore的TEST集合中读取对应用户的Role和UID字段,根据用户角色展示差异化页面内容,执行读取逻辑时触发上述报错。
相关代码
数据读取方法
Future ReadUserinDatabase(String email) async { QuerySnapshot querySnapshot = await FirebaseFirestore.instance.collection('TEST').where('Email', isEqualTo: "TEST@yahoo.com").get(); final allData1 = querySnapshot.docs.map((doc) => doc.get('Activity')).toList(); final allData2 = querySnapshot.docs.map((doc) => doc.get('CustomerID')).toList(); final allData3 = querySnapshot.docs.map((doc) => doc.get('Email')).toList(); final allData4 = querySnapshot.docs.map((doc) => doc.get('Role')).toList(); final allData5 = querySnapshot.docs.map((doc) => doc.get('UID')).toList(); print(allData1); print(allData2); print(allData3); print(allData4); print(allData5); } }
DatabaseUser数据模型定义
class DatabaseUser { final String CustomerID; final String Email; final String Role; final String Activity; final String UID; DatabaseUser( {required this.Email, required this.CustomerID, required this.Role, required this.Activity, required this.UID}); Map<String, dynamic> toJson() => { 'CustomerID': CustomerID, 'Email': Email, 'Role': Role, 'Activity': Activity, 'UID': UID }; static DatabaseUser fromJson(Map<String, dynamic> json) => DatabaseUser( Email: json['Email'], CustomerID: json['CustomerID'], Role: json['Role'], Activity: json['Activity'], UID: json['UID']); }
解决方案
这个报错的核心原因是类型转换不匹配:你虽然定义了DatabaseUser的序列化/反序列化方法,但读取方法没有指定明确的返回类型,也没有将Firestore返回的文档数据转换成DatabaseUser类型,大概率是在其他调用该方法的位置,误将Firestore查询返回的内部_JsonQuery类型对象直接赋值给了DatabaseUser类型的变量,触发运行时类型强转错误。
按以下步骤修改即可解决:
- 修正读取方法,直接返回结构化的
DatabaseUser对象,不要拆分字段存成多个独立列表,同时给方法指定明确的返回类型,在编译期拦截类型错误。
替换原有ReadUserinDatabase方法代码:Future<DatabaseUser?> ReadUserinDatabase(String email) async { // 注意:Firestore字符串匹配默认大小写敏感,要确保传入的email和库中存储格式完全一致 QuerySnapshot querySnapshot = await FirebaseFirestore.instance .collection('TEST') .where('Email', isEqualTo: email) // 替换硬编码的测试邮箱,使用传入的email参数 .limit(1) // 邮箱为用户唯一标识,加limit减少不必要的数据读取开销 .get(); if (querySnapshot.docs.isEmpty) { return null; // 处理未查询到对应用户的边界情况 } // 取第一条匹配文档的数据,调用预定义的fromJson方法完成类型转换 final docData = querySnapshot.docs.first.data() as Map<String, dynamic>; return DatabaseUser.fromJson(docData); } - 检查所有调用
ReadUserinDatabase的位置,确保接收返回值的变量类型为DatabaseUser?,不要写非空类型的强接收写法,也不要将Firestore原生查询实例直接赋值给DatabaseUser类型变量。 - 登录后获取用户角色和UID的参考调用逻辑:
// 登录流程拿到用户邮箱后调用读取方法 final DatabaseUser? currentUser = await ReadUserinDatabase(currentLoginEmail); if (currentUser != null) { String userRole = currentUser.Role; String userUid = currentUser.UID; // 在此处根据userRole的值做页面路由判断、差异化内容渲染即可 }
额外提示:你贴出的原有读取方法末尾多写了一个闭合大括号
},会触发语法错误,修改时记得删除多余符号。
内容的提问来源于stack exchange,提问作者Aiden P
相关产品推荐
相关产品推荐

