Flutter 校验Firestore购物车商品是否添加的方法执行异常问题
问题触发原因
- 主因:调用
remove方法时传入的是新创建的CartItem实例,Dart的List.remove()默认按内存引用匹配对象,新实例和_items列表中已存储的实例引用不相同,因此删除操作不会生效,_items长度无变化,isProductAddedToCart校验自然返回true。 - 隐藏bug:
add方法中遍历_items给cartMap赋值时,会反复覆盖title和name字段,最终调用arrayUnion写入Firestore的永远是_items列表最后一个商品的属性,多次添加商品后Firestore存储的数据会不符合预期。 - 异步逻辑问题:按钮点击回调中调用
add/remove后立刻打印校验结果,此时Firestore的异步操作还未完成,notifyListeners还没触发,打印的是旧状态的结果,不能代表最终执行状态。
修复方案
1. 修复remove删除不生效问题
将按引用删除改为按商品属性匹配删除:
void remove(BuildContext context, CartItem item) { // 按title匹配删除对应CartItem,替代默认的引用匹配逻辑 _items.removeWhere((element) => element.product?.title == item.product?.title); AuthService authService = Provider.of<AuthService>(context, listen: false); Map<String, dynamic> cartMap = { 'title': (item.product as Product).title, 'name': (item.product as Product).name }; _instance = FirebaseFirestore.instance; _instance!.collection('cart').doc(authService.getCurrentUser()).update({ 'cartProduct': FieldValue.arrayRemove([cartMap]), }).then((value) { print(_items.length); notifyListeners(); }); }
2. 修复add方法隐藏bug
不要遍历所有_items覆盖cartMap,直接构造当前新增商品的属性map:
void add(BuildContext context, CartItem item) { _items.add(item); AuthService authService = Provider.of<AuthService>(context, listen: false); // 仅构造当前新增商品的属性map Map<String, dynamic> cartMap = { 'title': (item.product as Product).title, 'name': (item.product as Product).name }; _instance = FirebaseFirestore.instance; _instance! .collection('cart') .doc(authService.getCurrentUser()) .update({ 'cartProduct': FieldValue.arrayUnion([cartMap]) }).then((value) { print(_items.length); notifyListeners(); }); }
3. 可选:优化异步逻辑感知操作结果
如果需要在操作完成后获取最新状态,可以将add/remove改为异步方法,调用时等待执行完成:
// 改造remove方法为异步 Future<void> remove(BuildContext context, CartItem item) async { _items.removeWhere((element) => element.product?.title == item.product?.title); AuthService authService = Provider.of<AuthService>(context, listen: false); Map<String, dynamic> cartMap = { 'title': (item.product as Product).title, 'name': (item.product as Product).name }; _instance = FirebaseFirestore.instance; await _instance!.collection('cart').doc(authService.getCurrentUser()).update({ 'cartProduct': FieldValue.arrayRemove([cartMap]), }); print(_items.length); notifyListeners(); } // 调用时添加await press: () async { print(cart.isProductAddedToCart(widget.product)); await cartService.remove(context, CartItem(product: widget.product)); print(cart.isProductAddedToCart(widget.product)); }
内容的提问来源于stack exchange,提问作者Ricky Kim
相关产品推荐
相关产品推荐

