Flutter报错:_InternalLinkedHashMap无法转换为bool类型求解决
问题分析
异常type '_InternalLinkedHashMap<String, dynamic>' is not a subtype of type 'bool'的核心原因是给Product的isFavorite字段传入了Map类型的值,而非预期的bool类型,触发点在这一行:
isFavorite: _favoriteData == null ? false : _favoriteData[prodId],
导致问题的两个关键错误:
- 请求URL错误:获取收藏数据时,错误复用了产品列表的
url,而非定义好的favoritesResponseUrl,导致favoriteResponse拿到的是产品Map数据,而非用户收藏的「产品ID: bool」键值对。 - 未处理收藏数据异常:即使请求正确,
_favoriteData[prodId]可能不存在、或返回非bool类型(如null),直接赋值会引发类型不匹配。
修复方案
步骤1:修正请求URL
把获取收藏数据的请求目标改为favoritesResponseUrl:
final favoriteResponse = await http.get(favoritesResponseUrl);
步骤2:安全处理收藏数据
- 先判断解析后的收藏数据是否为有效Map,避免强制转换报错
- 对
_favoriteData[prodId]做类型校验,确保最终传入bool值
完整修正代码
Future<void> fetchAndSetProducts([bool filterByUser = false]) async { final filterString = filterByUser ? 'orderBy="userId"&equalTo="${userId}"' : ''; final Uri url = Uri.parse( 'https://flutter-update-8df10-default-rtdb.europe-west1.firebasedatabase.app/products.json?auth=${authToken}&${filterString}'); try { final response = await http.get(url); final extractedData = json.decode(response.body) as Map<String, dynamic>?; if (extractedData == null || extractedData.isEmpty) { print('extractedDataProducts is empty'); return; } final Uri favoritesResponseUrl = Uri.parse( 'https://flutter-update-8df10-default-rtdb.europe-west1.firebasedatabase.app/UserFavorites/${userId}.json?auth=${authToken}'); final favoriteResponse = await http.get(favoritesResponseUrl); // 安全解析收藏数据 final favoriteJson = json.decode(favoriteResponse.body); Map<String, dynamic>? _favoriteData; if (favoriteJson != null && favoriteJson is Map<String, dynamic>) { _favoriteData = favoriteJson; } final List<Product> loadedProducts = []; extractedData.forEach((prodId, prodData) { // 确保isFavorite为bool类型 final isFavorite = _favoriteData?[prodId] is bool ? _favoriteData![prodId] : false; loadedProducts.add(Product( id: prodId, title: prodData['title'], description: prodData['description'], price: prodData['price'], isFavorite: isFavorite, imageUrl: prodData['imageUrl'], )); }); _items = loadedProducts; notifyListeners(); } catch (error) { print(error); rethrow; } }
额外优化建议
- 将
extractedData类型改为Map<String, dynamic>?,并判断isEmpty,覆盖Firebase返回空对象的场景 - 用
rethrow代替throw (error),保留原始异常的调用栈信息 - 对
prodData的字段添加空值兜底(如prodData['title'] ?? '默认标题'),避免接口字段缺失引发的异常
内容的提问来源于stack exchange,提问作者ASCI
相关产品推荐
相关产品推荐

