i have a search bar that receives a query string from the user, if the query string is empty, like i just initiated the search operation, it fetches all documents in posts collection...if user starts typing inside the search bar...it takes the typed text and compare it to a field inside each document in firestore collection and if it matches...its retrieves matched documents and it and previews them in screen, if the user deleted his typed query string...so the query string is empty again...so it fetches all documents again...i use provider package to conduct the query string to database fetch function like so:
Provider:
import 'package:flutter/foundation.dart';
class QueryStringProvider extends ChangeNotifier {
String _queryString = '';
String getQueryString() => _queryString;
updateQueryString(String userQueryString) {
_queryString = userQueryString;
notifyListeners();
}
}
the database function:
Stream<QuerySnapshot> filterAllPosts(String query) {
return query.isEmpty
? _postsCollection.snapshots()
: _postsCollection
.where('postSubtitles', arrayContains: query)
.snapshots();
}
the following is a stream builder wrapped inside a Consumer<QueryStringProvider>, the Streambuilder receives all data retrieved from database fetch function, and populate the data according to my preferred layout structure:
@override
Widget build(BuildContext context) {
return Container(
child: Consumer<QueryStringProvider>(
builder: (context, data, _) {
return StreamBuilder<QuerySnapshot>(
// stream: DatabaseService().listenToAllGigs(),
stream: DatabaseService().filterAllGigs(data.getQueryString()),
builder: (context, snapshot) {
return !snapshot.hasData
? Center(child: Text(''))
: snapshot.data.documents.length > 0
? ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot data =
snapshot.data.documents[index];
Map getDocData = data.data;
return GestureDetector(
child: PostItem(
appointed: getDocData['appointed'],
appointedUserFullName:
getDocData['appointedUserFullName'],
postId: getDocData['gigId'],
postTitle: getDocData['postTitle'],
postSubtitles: getDocData['postSubtitles'],
postBody: getDocData['postBody'],
// onDeleteItem: () => model.deleteGig(index),
),
);
})
: Center(
child: Text(
'No Posts matching your criteria',
style: TextStyle(fontSize: 16),
));
},
);
},
),
);
}
i have three questions about how to reduce cloud reads with the above code:
1) is there any problems that i fetch all documents when i initiate the search operation and the query string is empty?
2)when users starts typing inside the search bar...does this mean that all the fetched data get lost..and we are making new reads again with filtering?...or it just filters what i've already fetched from initiating the search operation from the start?
3) when user deletes the query string and cancels filtering and and query string is now empty...does this mean that i will make a new full read to the cloud collection again...so everytime the users types or deletes the query string i iterate through all the collection again?*
Execuse me if the question is too long...but it is much closer to theoretical concepts rather than code...
any clarifications would be much appreciated...
many thanks.