Flutter Firestore技术问题:展开ListView时如何获取并展示集合中的Map数据及解决类型转换错误
Hey there, let's break down the type error you're seeing: type 'String' is not a subtype of type 'int' of 'index'. This is telling you that somewhere in your code, you're trying to use a string as an index for a collection that expects an integer (like a List).
What's Causing the Issue?
Looking at your code, you're accessing doc['orderDetails']['quantity'] directly — but this assumes orderDetails is a single Map. Chances are, your Firestore orders collection has orderDetails stored as an array (List) of Maps, where each item in the array represents one product in the order.
When you try to use ['quantity'] on a List, Dart throws that error because Lists only accept integers as indices (like [0], [1]), not strings.
How to Fix It
We need to treat orderDetails as a List and iterate over its items to display each product's quantity and title. Here's the corrected code for the expanded section, plus a fix for a common UI issue:
Step 1: Fix the Expanded Order Items Display
Replace your existing expanded SizedBox with this code:
if (_expanded) SizedBox( height: 100.0, child: ListView.builder( itemCount: (doc['orderDetails'] as List).length, itemBuilder: (ctx, index) { // Explicitly cast the item to a Map for type safety final orderItem = doc['orderDetails'][index] as Map<String, dynamic>; return Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( '${orderItem['quantity']}x', style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500), ), Text( orderItem['title'], style: TextStyle(fontSize: 16), ), ], ), ); }, ), )
Step 2: Fix the Global Expand State (Optional but Recommended)
Right now, your _expanded variable is shared across all orders — clicking one expand button will expand every order. To fix this, track each order's expand state individually:
- Add a map to your state class to track expand status per document ID:
class _OrdersScreenState extends State<OrdersScreen> { // Track expand state for each order using its document ID Map<String, bool> _expandedOrders = {}; @override Widget build(BuildContext context) { // ... rest of your code } }
- Update the IconButton's onPressed and the expand condition:
// In the ListTile's trailing IconButton onPressed: () { setState(() { // Toggle the state for this specific order _expandedOrders[doc.id] = !(_expandedOrders[doc.id] ?? false); }); }, // Update the expand condition if (_expandedOrders[doc.id] ?? false) SizedBox( // ... the ListView.builder from Step 1 )
Key Notes
- Type Safety: Always explicitly cast Firestore data to the expected type (like
as Listoras Map<String, dynamic>) to avoid runtime surprises. - Firestore Structure: Double-check your
orderscollection to confirmorderDetailsis indeed an array of objects withquantity(int) andtitle(string) fields.
内容的提问来源于stack exchange,提问作者supremo

