Dart中Firebase对象转CartItem实体类时company属性返回null问题
问题场景
我通过以下代码读取Firebase集合文档:
collectionRef.get().then( (querySnapshot) { print("All Orders"); for (var docSnapshot in querySnapshot.docs) { var _product = docSnapshot.data(); print(CartItem.fromJson(_product).company); } }, onError: (e) => print("Error completing: $e"), );
打印出的原始文档数据显示,每个条目都带有company: Choose Company字段:
[{quantity: 1, price: null, model: TP WM TWT95-P102GB, company: Choose Company, id: 2023-06-08 16:45:20.388836, title: null}, {quantity: 1, price: null, company: Choose Company, model: KD-65X75L IN5, id: 2023-06-08 16:45:20.838656, title: null}, {quantity: 1, price: null, model: HM SAC RAS222PCAIBA, company: Choose Company, id: 2023-06-08 16:45:21.499394, title: null}]
但通过CartItem.fromJson转换为对象后,打印company属性始终返回null,日志如下:
I/flutter (12337): All Orders I/flutter (12337): null I/chatty (12337): uid=10091(com.example.ts) 1.ui identical 1 line I/flutter (12337): null
当前CartItem.fromJson的实现代码:
CartItem.fromJson(Map<String, Object?> json) : this( id: json['id'] as String?, title: json['title'] as String?, quantity: json['quantity'] as int?, price: json['price'] as double?, company: json['company'] as String?, model: json['model'] as String?, );
排查与解决方案
1. 修复类型转换逻辑
从原始数据看company是字符串,但直接用as String?强制转换可能因Firebase返回的字段类型为dynamic导致转换失败。改用更安全的转换方式:
CartItem.fromJson(Map<String, Object?> json) : this( id: json['id']?.toString(), title: json['title']?.toString(), quantity: json['quantity'] as int?, price: json['price'] is num ? (json['price'] as num).toDouble() : null, company: json['company']?.toString(), model: json['model']?.toString(), );
2. 校验Firebase字段名匹配度
确认Firebase文档中的字段名和代码中的company完全一致——检查是否存在大小写错误、拼写错误或多余空格(比如实际字段名是Company或company_name),字段名不匹配会直接导致json['company']返回null。
3. 调试原始数据结构
在循环中添加调试打印,确认company字段的实际状态:
for (var docSnapshot in querySnapshot.docs) { var _product = docSnapshot.data(); print('原始文档数据: $_product'); print('直接获取company: ${_product['company']}'); print('转换后company: ${CartItem.fromJson(_product).company}'); }
如果直接打印_product['company']也返回null,说明Firebase文档中该字段确实不存在或为空;如果能正常输出Choose Company,则问题完全出在fromJson的转换逻辑上。
4. 增强空安全的严谨性
避免强制类型转换的潜在风险,改用类型判断后转换:
company: json['company'] is String ? json['company'] as String : null,
也可以添加异常捕获定位问题:
try { var rawCompany = json['company']; print('company原始值: $rawCompany, 类型: ${rawCompany.runtimeType}'); var company = rawCompany as String?; } catch (e) { print('company转换异常: $e'); }
内容的提问来源于stack exchange,提问作者Mohit H

