You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter购物车无法显示Firestore商品及总价计算异常问题求助

Hey there! Let's tackle your two Flutter e-commerce issues one by one, with fixes tailored to your code:

Issue 1: Firestore Products Not Showing in Cart Page

Looking at your StreamBuilder code, here are the likely culprits and fixes:

1.1 Invalid userCartList Initialization

Your checkout button checks if userCartList.length == 1 to show an empty cart message—this suggests your cart list is initialized with an empty string ([""]) instead of an empty array ([]). When Firestore runs the whereIn query with this list, it looks for items with an empty shortInfo (which don't exist), leading to no results.

Fix: Update your shared preferences initialization to set an empty list by default:

// Run this once when your app starts (e.g., in main.dart or auth screen)
if (!EcommerceApp.sharedPreferences.containsKey(EcommerceApp.userCartList)) {
  EcommerceApp.sharedPreferences.setStringList(EcommerceApp.userCartList, []);
}

Then adjust your checkout button's empty cart check to use isEmpty:

if (EcommerceApp.sharedPreferences.getStringList(EcommerceApp.userCartList)?.isEmpty ?? true) {
  Fluttertoast.showToast(msg: "Your Cart is empty!");
}

1.2 Filter Invalid IDs in whereIn Query

Even if you fix initialization, there might be stray empty IDs in the cart list. Add a filter to remove empty strings before passing to Firestore:

stream: EcommerceApp.firestore.collection("/items")
  .where("shortInfo", whereIn: EcommerceApp.sharedPreferences.getStringList(EcommerceApp.userCartList)?
      .where((id) => id.isNotEmpty)
      .toList() ?? []
  ).snapshots(),

1.3 Improve StreamBuilder Loading State Handling

Your current code only checks !snapshots.hasData for loading, but you should explicitly handle the connection state to avoid glitches:

builder: (context, snapshots) {
  // Show loading spinner while fetching data
  if (snapshots.connectionState == ConnectionState.waiting) {
    return SliverToBoxAdapter(child: Center(child: circularProgress()),);
  }
  
  // Show empty cart if no valid items exist
  if (!snapshots.hasData || snapshots.data!.docs.isEmpty) {
    return beginBuildinCart();
  }
  
  // Proceed to build cart items
  // ... rest of your code
}

Issue 2: Total Price Calculation Not Working

Your current approach of calculating total amount inside the SliverChildBuilderDelegate is unreliable because list items can be rebuilt/reused by Flutter, leading to incorrect or duplicate calculations. Here's a better approach:

2.1 Calculate Total Price Before Building List Items

Compute the total once you have the Firestore data, outside the item builder, to ensure accuracy:

StreamBuilder<QuerySnapshot>(
  stream: // ... your corrected stream,
  builder: (context, snapshots) {
    // ... loading and empty state checks from Issue 1 ...

    // Calculate total price once for all items
    double calculatedTotal = 0.0;
    final cartItems = snapshots.data!.docs;
    
    for (var doc in cartItems) {
      ItemModel model = ItemModel.fromJson(doc.data() as Map<String, dynamic>);
      calculatedTotal += model.price;
    }

    // Update TotalAmount provider after the widget frame is built
    WidgetsBinding.instance.addPostFrameCallback((_) {
      Provider.of<TotalAmount>(context, listen: false).display(calculatedTotal);
    });

    // Build the cart items list
    return SliverList(
      delegate: SliverChildBuilderDelegate(
        (context, index) {
          ItemModel model = ItemModel.fromJson(cartItems[index].data() as Map<String, dynamic>);
          return sourceInfo(
            model, 
            context, 
            removeCartFunction: () => removeItemFromUserCart(model.shortInfo)
          );
        },
        childCount: cartItems.length
      ),
    );
  },
)

2.2 Verify TotalAmount Provider Implementation

Make sure your TotalAmount class correctly notifies listeners when updating the total:

class TotalAmount extends ChangeNotifier {
  double _totalAmount = 0.0;

  double get totalAmount => _totalAmount;

  void display(double newAmount) {
    _totalAmount = newAmount;
    notifyListeners(); // Critical to update UI
  }
}

2.3 Fix removeItemFromUserCart to Update State

Ensure removing an item updates both shared preferences and the CartItemCounter provider (to refresh the total price and cart item count):

void removeItemFromUserCart(String shortInfoAsId) {
  List<String> updatedCart = EcommerceApp.sharedPreferences.getStringList(EcommerceApp.userCartList)!;
  updatedCart.remove(shortInfoAsId);
  
  // Save updated cart to shared preferences
  EcommerceApp.sharedPreferences.setStringList(EcommerceApp.userCartList, updatedCart);
  
  // Update cart item count provider
  Provider.of<CartItemCounter>(context, listen: false).displayResult(updatedCart.length);
}

These changes should resolve both the missing cart items and incorrect total price issues. Let me know if you run into any edge cases!

内容的提问来源于stack exchange,提问作者Mohamed Keke

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 11:23:34