Skip to content

Instantly share code, notes, and snippets.

@hyochan
Last active January 17, 2023 09:01
Show Gist options
  • Save hyochan/ad76c1b90e3771d1fe149462a70ce276 to your computer and use it in GitHub Desktop.
Save hyochan/ad76c1b90e3771d1fe149462a70ce276 to your computer and use it in GitHub Desktop.
Solving firestore whereIn query limitation
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;
@hyochan
Copy link
Author

hyochan commented Jan 16, 2023

Future<List<PostModel>> getMany({
  List<Object> whereIn = [],
  int size = 20,
}) async {
  var query = FirebaseFirestore.instance.doc('app').collection('posts')
      .withConverter<PostModel>(
        fromFirestore: (snapshot, _) =>
            PostModel.fromJson(snapshot.data() ?? {}),
        toFirestore: (post, _) => post.toJson(),
      )
      .limit(size)
      .where('userRef', whereIn: whereIn);
  
  var snap = await query.get();
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment