Flutter+Cloud Firestore+Provider:返回商品页数据重复问题求助
问题分析
数据重复的核心原因是fetchProducts方法每次调用都会将Firestore返回的商品追加到_products列表中,未清空旧数据;若页面切换时触发该方法重复执行,就会导致列表出现大量重复项。
解决方案
方案1:获取新数据前清空旧列表(最简方案)
修改Products类的fetchProducts方法,在请求数据前先清空本地列表,确保每次都是全新的数据集,同时优化通知时机减少UI重建:
Future<void> fetchProducts() async { // 清空旧数据 _products.clear(); final snapshot = await FirebaseFirestore.instance .collection('products') .orderBy('id', descending: true) .get(); for (var doc in snapshot.docs) { _products.insert( 0, Product( id: doc['id'], title: doc['title'], price: doc['price'], imageUrl: doc['imageUrl'], )); } // 所有数据加载完成后统一通知更新UI notifyListeners(); }
方案2:仅添加新商品(适合保留本地修改场景)
如果需要保留本地对商品的修改(如收藏状态),可以通过商品ID判断是否已存在,只添加Firestore返回的新商品:
Future<void> fetchProducts() async { final snapshot = await FirebaseFirestore.instance .collection('products') .orderBy('id', descending: true) .get(); for (var doc in snapshot.docs) { // 检查当前商品是否已在本地列表中 final isExist = _products.any((prod) => prod.id == doc['id']); if (!isExist) { _products.insert( 0, Product( id: doc['id'], title: doc['title'], price: doc['price'], imageUrl: doc['imageUrl'], )); } } notifyListeners(); }
额外优化:防止重复触发请求
在Products类中添加加载状态,避免同一时间多次调用fetchProducts:
class Products with ChangeNotifier { final List<Product> _products = []; bool _isLoading = false; // 新增加载状态标记 Future<void> fetchProducts() async { if (_isLoading) return; // 正在加载时直接返回,避免重复请求 _isLoading = true; try { _products.clear(); final snapshot = await FirebaseFirestore.instance .collection('products') .orderBy('id', descending: true) .get(); for (var doc in snapshot.docs) { _products.insert( 0, Product( id: doc['id'], title: doc['title'], price: doc['price'], imageUrl: doc['imageUrl'], )); } } catch (e) { // 可添加错误处理逻辑 print('加载商品失败:$e'); } finally { _isLoading = false; notifyListeners(); } } List<Product> get items { return [..._products]; } }
内容的提问来源于stack exchange,提问作者supremo
相关产品推荐
相关产品推荐

