I have a small function for my application that fetches cart items from firebase and displays them. The application was working fine till Flutter version 2.5.2 but when I moved 2.8.1 the application crashed if the number of items in the cart collection are more than 10 because of the firebase query limit of "<=10"
[Unhandled promise rejection: FirebaseError: Invalid Query. 'in' filters support a maximum of 10 elements in the value array.]
If you can suggest a workaround for this, that would be really helpful.
I am currently using the following functions to get data from firebase.
///Get products
Stream<List<Product>> getProducts(List<CartItem> cartItems) {
List<String> ids = cartItems.map((e) => e.reference).toList();
return database.getDataWithArrayCondition('products', ids).map(
(snapshots) => snapshots.docs
.map((snapshot) => Product.fromMap(
snapshot.data() as Map<String, dynamic>, snapshot.id))
.toList());
}
///Get cart items
Stream<List<CartItem>> _getCartItems() {
return database
.getDataFromCollection("users/${auth.uid}/cart")
.map((snapshots) => snapshots.docs.map((snapshot) {
return CartItem.fromMap(
snapshot.data() as Map<String, dynamic>, snapshot.id);
}).toList());
}
Error
The following assertion was thrown building StreamBuilder<List<CartItem>>(dirty, state: _StreamBuilderBaseState<List<CartItem>, AsyncSnapshot<List<CartItem>>>#978e8):
'in' filters support a maximum of 10 elements in the value [List].
'package:cloud_firestore/src/query.dart':
Failed assertion: line 702 pos 11: '(value as List).length <= 10'
The relevant error-causing widget was:
StreamBuilder<List<CartItem>> StreamBuilder:file:///Users/Osamah/Downloads/grocery_user_fixed-master/lib/ui/home/cart/cart.dart:265:12
When the exception was thrown, this was the stack:
#2 _JsonQuery.where (package:cloud_firestore/src/query.dart:702:11)
#3 FirestoreDatabase.getDataWithArrayCondition (package:grocery/services/database.dart:150:10)
#4 CartBloc.getProducts (package:grocery/blocs/cart_bloc.dart:32:21)
#5 _CartState.build.<anonymous closure> (package:grocery/ui/home/cart/cart.dart:292:37)
#6 StreamBuilder.build (package:flutter/src/widgets/async.dart:442:81)
#7 _StreamBuilderBaseState.build (package:flutter/src/widgets/async.dart:124:48)
#8 StatefulElement.build (package:flutter/src/widgets/framework.dart:4705:27)
#9 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:4588:15)
#10 StatefulElement.performRebuild (package:flutter/src/widgets/framework.dart:4763:11)
#11 Element.rebuild (package:flutter/src/widgets/framework.dart:4311:5)
#12 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2578:33)
#13 WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:882:21)
#14 RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:363:5)
#15 SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1145:15)
#16 SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:1082:9)
#17 SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:996:5)
#21 _invoke (dart:ui/hooks.dart:150:10)
#22 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:270:5)
#23 _drawFrame (dart:ui/hooks.dart:114:31)
(elided 5 frames from class _AssertionError and dart:async)
Here is the relevant code
return StreamBuilder<List<CartItem>>(
stream: widget.bloc.cartItems,
builder: (context, snapshot) {
if (snapshot.hasData && snapshot.data != null) {
List<CartItem> cartItems = snapshot.data!;
if (cartItems.length == 0) {
return FadeIn(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
SvgPicture.asset(
'images/state_images/empty_cart.svg',
width: width * 0.5,
fit: BoxFit.cover,
),
Padding(
padding: EdgeInsets.only(top: 30),
child: Texts.headline3(
'Nothing found here\nGo and enjoy shopping!',
themeModel.accentColor,
alignment: TextAlign.center),
)
]),
);
} else {
return StreamBuilder<List<Product>>(
stream: widget.bloc.getProducts(cartItems),
builder: (context, snapshot) {
if (snapshot.hasData && snapshot.data != null) {
List<Product> products = snapshot.data!;
cartItems = cartItems.where((cartItem) {
if (products.where((product) {
if (cartItem.reference == product.reference) {
cartItem.product = product;
return true;
} else {
return false;
}
}).length ==
0) {
return false;
} else {
return true;
}
}).toList();