Last active
January 17, 2023 09:01
-
-
Save hyochan/ad76c1b90e3771d1fe149462a70ce276 to your computer and use it in GitHub Desktop.
Solving firestore whereIn query limitation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import '../utils/firebase_config.dart'; | |
abstract class IQueryService { | |
Future<List<T>> getWhereInQueryList<T>({ | |
required List<Object> whereInList, | |
required CollectionReference<Map<String, dynamic>> reference, | |
int size, | |
startAfter, | |
}); | |
} | |
class QueryService implements IQueryService { | |
const QueryService._(); | |
static QueryService instance = const QueryService._(); | |
Future<List<Map<String, dynamic>>> _queryList({ | |
required List<Object> whereInList, | |
required CollectionReference<Map<String, dynamic>> reference, | |
startAfter, | |
String searchText = '', | |
String searchColumn = 'title', | |
int size = 10, | |
}) async { | |
if (whereInList.isEmpty) { | |
return []; | |
} | |
var query = reference | |
.limit(size) | |
.where('userRef', whereIn: whereInList) | |
.where('deletedAt', isNull: true); | |
query = searchText.isEmpty | |
? query.orderBy('createdAt', descending: true) | |
: query | |
.where(searchColumn, isGreaterThanOrEqualTo: searchText) | |
.where(searchColumn, isLessThanOrEqualTo: '$searchText\uf8ff'); | |
query = startAfter != null ? query.startAfter([startAfter]) : query; | |
var snap = await query.get(); | |
if (snap.docs.isEmpty) { | |
return []; | |
} | |
return snap.docs.map((e) => e.data()).toList(); | |
} | |
@override | |
Future<List<T>> getWhereInQueryList<T>({ | |
required List<Object> whereInList, | |
int size = 10, | |
startAfter, | |
}) async { | |
var whereInListBy10 = []; | |
for (var i = 0; i < ((whereInListBy10.length / 10) + 1); i++) { | |
var current10 = i * 10; | |
var next10 = (i + 1) * 10; | |
var whereIn = whereInList.length > current10 | |
? whereInList.sublist( | |
current10, | |
whereInList.length > next10 ? next10 : whereInList.length, | |
) | |
: <Object>[]; | |
whereInListBy10.add(whereIn); | |
} | |
var fetchedList = <T>[]; | |
for (var ref in whereInListBy10) { | |
var i = whereInListBy10.indexOf(ref); | |
var whereInList = whereInListBy10[i]; | |
var fetchedItems = await _queryList( | |
whereInList: whereInList, | |
size: size, | |
startAfter: startAfter, | |
); | |
fetchedList.addAll(fetchedItems as List<T>); | |
} | |
return fetchedList; | |
} | |
} | |
/// Usage | |
var list = await getWhereInQueryList( | |
reference: FirebaseFirestore.instance | |
.collection('your_app') | |
.doc('app') | |
.collection('posts'), | |
whereInList: followerRefs, | |
size: size, | |
startAfter: startAfter, | |
); | |
var posts = <PostModel>[]; | |
for (var el in list) { | |
var post = PostModel.fromJson(el); | |
posts.add(post); | |
} | |
posts.sort((a, b) => b.createdAt.compareTo(a.createdAt)); | |
return posts; |
Author
hyochan
commented
Jan 16, 2023
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment