Flutter/Dart运行出现_TypeError (type 'String' is not a subtype of type 'int' of 'index')错误如何解决?
错误原因
- 核心错误:
fetchAndSetOrders方法中查询订单数据误用了http.post请求。Firebase Realtime Database 中获取数据需要用 GET 请求,POST 请求是用来新增数据的,请求后返回的结果仅为新生成的条目ID(结构为{"name": "新生成的订单ID"}),不是你需要的全量订单列表。 - 你把 POST 返回的结构强转为订单结构后,遍历的时候
orderData实际是字符串类型的订单ID,对字符串用['amount']访问属性时,字符串的下标要求是int类型,你传入了字符串类型的key,就触发了这个类型错误。 - 其他潜在问题:
- 数据类型转换缺失:从接口拿到的
amount是num类型,直接赋值给double类型的字段可能触发类型错误 - 空安全处理不严谨:直接将
json.decode(response.body)强转为Map<String, dynamic>如果返回为空会直接抛错,应该用可空类型接收
- 数据类型转换缺失:从接口拿到的
修复方案
- 把
fetchAndSetOrders中的POST请求改为GET请求,将final response = await http.post(Uri.parse(url));
修改为final response = await http.get(Uri.parse(url)); - 优化空安全和类型转换,修改后的
fetchAndSetOrders完整代码如下:
Future<void> fetchAndSetOrders() async { const url = 'https://shopapp-6740d-default-rtdb.firebaseio.com/orders.json'; final response = await http.get(Uri.parse(url)); final List<OrderItem> loadedOrders = []; // 用可空类型接收解析结果,避免空数据报错 final extractedData = json.decode(response.body) as Map<String, dynamic>?; if(extractedData == null){ return; } extractedData.forEach((orderId, orderData) { loadedOrders.add( OrderItem( id: orderId, // 显式转为double,空值兼容 amount: orderData['amount']?.toDouble() ?? 0.0, dateTime: DateTime.parse(orderData['dateTime'] as String), products: (orderData['products'] as List<dynamic>) .map( (item) => CartItem( id: item['id'] as String, title: item['title'] as String, quantity: item['quantity'] as int, price: item['price']?.toDouble() ?? 0.0, ), ) .toList(), ), ); }); _orders = loadedOrders.reversed.toList(); notifyListeners(); }
- 可选兼容优化:如果出现products字段解析为Map的异常(部分场景下Firebase会把数组转为键为数字的Map),可以加一层类型判断兼容:
// 解析products前先判断类型 List<dynamic> productList; if (orderData['products'] is List) { productList = orderData['products'] as List<dynamic>; } else { productList = (orderData['products'] as Map<String, dynamic>).values.toList(); } // 后续用productList做map转换生成CartItem列表
内容的提问来源于stack exchange,提问作者allaith
相关产品推荐
相关产品推荐

