How to get all documents from a collection without using StreamBuilder? - flutter

I want to get all documents from firestore collection without using stream builder, otherwise I will have nested streams and in the last stream I am getting a null. Initial data is not solving my problem.
Now I make a stream builder for that collection, when a snapshot is chosen I jump on other widget and there I also make a stream builder and here is the problem.
I want to make stream builder only in the last widget of the scenario, because only there realtime data update is needed.

You can use FutureBuilder with the following method
await Firestore.instance.collection("books").getDocuments()

Get Realtime data using this:
Firestore.instance
.collection('books').snapshots().listen((querySnapshot){
});

Related

How the Firebase Firestore's snapshots() is made and how it can listen to the database updates with a stream inside the flutter app

in the snapshots() method that returns a Stream of document or collection snapshots from Firestore's database:
FirebaseFirestore.instance.collection("collection").snapshots();
How the stream is done, I mean what should I know and learn in order to make as an example a Stream that will listen to endpoint/database changes?
I have an idea about using web sockets but I don't think this is what it's used in the snapshots().
and I don't want some way to create a Stream that requests new data every n Duration.
I want something that does nothing when nothing happens in the backend, but once we change something the Stream should know about it and listen to it.
Thank you!
You have the first part right already. Store it in a variable.
final myStream = FirebaseFirestore.instance.collection("collection").snapshots();
Next, you need to use a StreamBuilder pass in your stream
StreamBuilder(
stream: myStream,
builder: (context, AsyncSnapshot response) {
if(response.connectionState==Connectionstate.waiting) return const CircularProgressIndicator();
final data = response.data();
return WidgetToDisplayData()
}
),
Pass all the other required arguments including the builder widget, which refers to what you want. Firebase has a caching mechanism that ensured a listener is only active if there are changes detected in the db

Get stream of data from DB | Sembast | Flutter

I'm working with Sembast nowadays and was wondering If there's any way to create a stream of data that could get me all the values inside the DB. My requirement is to setup a listener on that stream so that whenever the data change is triggered, I could do something with it.
Documentation on Sembast is pretty limited and I'm now sure how I can do this. Usually I use the .find method to fetch all the values from within my db. I've been using a stringMapFactory to store my records.
Can we do this ? Any help would be really appreciated.
Sorry for the poor documentation.
It is quite similar to firestore. You can listen to all changes in a store
// Track every store changes
var query = store.query();
var subscription = query.onSnapshots(db).listen((snapshots) {
// snapshots always contains the list of all records
// ...
});
Basically you have a query on the store (with or without filter) that you can query or listen for changes.
See https://pub.dev/documentation/sembast/latest/sembast/QueryRef/onSnapshots.html
https://github.com/tekartik/sembast.dart/blob/master/sembast/doc/change_listener.md
If you use Hive as db, may use Hive Box as listenable.
ValueListenableBuilder<Box<YOUR_BOX_MODEL>>(
valueListenable: box.listenable(),
builder: (context,value,child){}
)

How can I access/manipulate data from a Stream inside a Bloc in Flutter?

After calling a method in my Bloc that returns a Stream<List> from Firebase, I need to perform some logic on the data that comes from the stream (e.g. filter the data based on the userId). The problem I run into is that I can't use async/await on the stream because it throws an error saying "Functions marked 'async' must have a return type assignable to 'Future'. " Are there any strategies/patterns for accessing a stream's data inside a Bloc or does all the data manipulation need to be done in the widget with a StreamBuilder?
Use asyncMap for asynchronous mapping.
Creates a new stream with each data event of this stream asynchronously mapped to a new event.

Firestore How to access a value from a snapshot in a Document Snapshot stream

I'm new to dart/flutter and am building an app right now that keeps track of some data on each user in a firstore database. I have a 'Users' collection which contains a document for each user, and one of the fields in the user document is the "UID" received through firebase_auth.
That being said, to make sure I have access to the latest copy of a user document, I hold a Stream. I want to somehow access the "UID" field from the latest snapshot in the stream and then do some other operations with it.
Is there anyway to do this? Am I using/understanding streams incorrectly?
If you only ever need the UID to build other widgets, you can simply use a StreamBuilder which will rebuild its children whenever a new value is emitted from the stream (which you get a copy of). However, if you need to access the latest UID at some arbitrary point of time, check out RxDart's BehaviorSubject which provides constant-time synchronous access to the latest emitted value, if one exists. It is very helpful for handling state in general.

How to get progression of getDocuments firestore

I am retrieving a lot of documents from Firestore, it can take a lot of time depending on the network connection of the user.
I would like to display a progres bar.
I didn't find any documentation on this
Here is my code :
final databaseReference = Firestore.instance;
databaseReference.collection("XXX").getDocuments().then((QuerySnapshot snapshot) {
Map<String, Transac.Transaction> map = new Map<String, Transac.Transaction>();
snapshot.documents.forEach((f) {
//doing something
});
I would like to have a percentage of the data loaded. For example :
Loading (58%)
Thank you.
Firestore doesn't expose any progress indicator for the documents within a query. By the time your then callback gets called, all documents have been loaded on the client and are present in the QuerySnapshot.
The usual way to deal with this is to show a "spinner" instead of a progress bar, and then hide that spinner as the first code inside your then callback.
What you can do instead is just call getDocument() for each document individually, and track their individual completions. You should track them in the order that you issued them, as the requests are pipelined over a single connection. This would give you a rough sense of progress, if you're requesting lot of documents.