I made a search bar for my Flutter App and put a filtering button next to this search bar.
When the user clicks on this filtering button, a 'bottom sheet' will open on the screen and user can select multiple filter (refer image) and apply
I want only the ads that match those filters to be shown on the screen. On the bottom sheet that opens, the user should be able to view the list of ads with the fields in the image (type, age, sex, gender, etc.). It would be easy if I used only type as a range filter option and paging. But there are multiple range filters and I don't know how to do that.
How can I combine these multiple queries? For the user experience, I want the user to quickly find listings that match the criteria they have in mind using multiple filters.
My service class named PetAdoptionService
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:my_pet_app/core/models/animals/pet_adoption_model.dart';
import 'package:my_pet_app/core/services/animals/pet_service.dart';
class PetAdoptionService extends PetService<PetAdoption> {
final CollectionReference _petsRef =
FirebaseFirestore.instance.collection('petAdoptions');
Future<List<PetAdoption>> getPetsByName(String name) async {
final querySnapshot = await _petsRef.get();
final pets = <PetAdoption>[];
for (final doc in querySnapshot.docs) {
final data = doc.data()! as Map<String, dynamic>;
final petName = data['name'] as String;
if (petName.toLowerCase().contains(name.toLowerCase())) {
pets.add(PetAdoption.fromMap(data));
}
}
return pets;
}
// The function that will search with more than one query should be defined here.
}
I managed to solve my problem. Since I think that other friends will have a similar problem with me in the future, I have given the correct code below for the benefit of these friends. I hope it will be useful to everyone.
class PetAdoptionService extends PetService<PetAdoption> {
final CollectionReference _petsRef =
FirebaseFirestore.instance.collection('petAdoptions');
// Function that allows a single query
Future<List<PetAdoption>> getPetsByName(String name) async {
final querySnapshot = await _petsRef.get();
final pets = <PetAdoption>[];
for (final doc in querySnapshot.docs) {
final data = doc.data()! as Map<String, dynamic>;
final petName = data['name'] as String;
if (petName.toLowerCase().contains(name.toLowerCase())) {
pets.add(PetAdoption.fromMap(data));
}
}
return pets;
}
// Function that allows multiple queries
Future<List<PetAdoption>> getFilteredPets({
String? type,
List<String>? breeds,
String? gender,
bool? isVaccinated,
bool? isNeutered,
String? city,
String? district,
}) async {
Query query = _petsRef;
if (type != null) {
query = query.where('type', isEqualTo: type);
}
if (breeds != null && breeds.isNotEmpty) {
query = query.where('breed', whereIn: breeds);
}
if (gender != null) {
query = query.where('gender', isEqualTo: gender);
}
if (isVaccinated != null) {
query = query.where('isVaccinated', isEqualTo: isVaccinated);
}
if (isNeutered != null) {
query = query.where('isNeutered', isEqualTo: isNeutered);
}
if (city != null) {
query = query.where('city', isEqualTo: city);
}
if (district != null) {
query = query.where('district', isEqualTo: district);
}
final querySnapshot = await query.get();
return querySnapshot.docs
.map((doc) => PetAdoption.fromMap(doc.data() as Map<String, dynamic>))
.toList();
}
}