How Can I Get Document name from AsyncSnapshot<QuerySnapshot> - flutter

The Goal
Get a document name from AsyncSnapshot<QuerySnapshot>
What I Did
In this collection users there is many documents which name is uid.
Using FutureBuilder and got AsyncSnapshot<QuerySnapshot>.
FutureBuilder(
future: FirebaseFirestore.instance
.collection("users")
.where('type', arrayContainsAny: ["Game", "Movie"])
.get(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) {
return Text(snapshot.error.toString());
}
if (snapshot.connectionState == ConnectionState.done) {
String uid = ...... // Want to get document id (= uid)
By using this snapshot, it was possible to get fields of each documents.
But ofcourse these don't include their own name.
How can I get document id from AsyncSnapshot<QuerySnapshot>?

snapshot.data!.docs can contain zero, 1 or more documents matching the criteria. This is a list of document snapshots.
So for example the first result can be in snapshot.data!docs[0]. From here to get the document id (in your case uid) simply use snapshot.data!docs[0].id.

Related

how to combine two Firestore collections?

Example code
toys = toysRef.where('postState', isEqualTo: 'recruiting').orderBy('createdAt', descending: true).snapshots();
fruits = fruitsRef.where('postState', isEqualTo: 'recruiting').orderBy('createdAt', descending: true).snapshots();
hi I'm trying to combine or merge two streams
I want to show toys and fruits order by desc with one StreamBuilder Widget
There is a common field ['createdAt']
I want to implement like this.
if some item added to firestore , it should show on realtime.
You can use StreamGroup from rxdart to merge your toys and fruits.
StreamGroup<List<QuerySnapshot>> combinedStreams = StreamGroup<List<QuerySnapshot>>.merge([
toysRef.where('postState', isEqualTo: 'recruiting').orderBy('createdAt', descending: true).snapshots(),
fruitsRef.where('postState', isEqualTo: 'recruiting').orderBy('createdAt', descending: true).snapshots()
]);
and to finally have them sorted in a stream, you could have:
StreamBuilder<List<QuerySnapshot>>(
stream: combinedStreams,
builder: (BuildContext context, AsyncSnapshot<List<QuerySnapshot>> snapshot) {
List<QueryDocumentSnapshot> combinedData = [];
for (QuerySnapshot snap in snapshot.data) {
combinedData.addAll(snap.docs);
}
combinedData.sort((a, b) => b['createdAt'].compareTo(a['createdAt']));
return ListView.builder(
itemCount: combinedData.length,
itemBuilder: (context, index) {
// Build your UI
}
);
}
)
You should use ListView.builder so that you have a performant list, and not render all the elements at once (would really lag your UI if you'd have a lot of elements).
Don't forget to check if snapshot has errors or is empty so that you can display a loader to the user or an error message.

Flutter, How to use firebase query .orderBy() on timestamp data?

I have stored time stamp data in firebase, I am fetching it using streams and displaying it in the latest date order in a datatable widget. I used .orderBy to access descending bool. But neither true nor false worked, instead !snapshot.hasData condition is getting executed, Why orderBy is not working and what are the other queries that I can use to get the latest date order.
stream: FirebaseFirestore.instance
.collection('lender')
.doc(auth.currentUser!.email)
.collection('paymentData')
.where('name',
isEqualTo: Provider.of<UpdateNameProvider>(context,
listen: false)
.bname).orderBy('paidDate', descending: true)
.snapshots(),
//.snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(
backgroundColor: Color(0xff8eacbb),
));
}
There are many possible reasons why a snapshot doesn't have data. At the very least you'll want to check if there's an error, and if so: log it somewhere.
Something like this:
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError) { // 👈
return Text(snapshot.error); // 👈
}
...
Try like this.
FirebaseFirestore.instance
.collection('lender')
.doc(auth.currentUser!.email)
.collection('paymentData')
.orderBy('paidDate', descending: true).where('name',
isEqualTo: Provider.of<UpdateNameProvider>(context,
listen: false)
.bname)
.snapshots(),

Retrieve from Firestore just the UserID in the array Flutter

Hello I have a stream Builder in firestore which display a list of user.
StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('Users').where('recentUser',arrayContainsAny: ['userId'])
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CupertinoActivityIndicator()
);
}
final data = snapshot.data!.docs;
in the Firestore collection I have a document which have userId Field and an array of user ID.
I am trying to retrieve the list of user and for a specific user I want to retrieve just the user that the id is in the array recentUser
As per above example I have tried to user .where('recentUser',arrayContainsAny: ['userId'])
but unsuccesfully...
Any idea?
try replacing ['userId'] with [userId] or ['$userId'] depending on type

Getting QuerySnapshot instead of DocumentSnapshot [FLUTTER]

StreamBuilder(
stream: FirebaseFirestore.instance.collection('users').snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return CircularProgressIndicator();
}
FirestoreUser firestoreUser =
FirestoreUser.fromDocument(snapshot.data); // Here snapshot.data is retrieving QuerySnapshot.
// How I can convert it to DocumentSnapshot
...
Hello StackOverflow users
I need to give to my new firestoreUser variable, which type of DocumentSnapshot. But I can't get it.
After writing snapshot.data it gives me an error called "QuerySnapshot is not subtype of DocumentSnapshot"
P.s I'm using StreamBuilder as you can see. Thank you
Your stream is FirebaseFirestore.instance.collection('users').snapshots() which is a QuerySnapshot, meaning, a List of QueryDocumentSnapshot which Extends DocumentSnapshot.
So if you want the documentSnapshot of every users in your 'users' collection, you will have to iterate over snapshot.data.docs:
But if you want to get the document of a particular user, then you can do:
StreamBuilder(
stream: FirebaseFirestore.instance.collection('users').doc(userID).snapshots(),
builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (!snapshot.hasData) {
return CircularProgressIndicator();
}
FirestoreUser firestoreUser =
FirestoreUser.fromDocument(snapshot.data);
...

How to retrun all documents to the list in flutter

I want to return my all documents in firestore my document in Identifier based on name but when I do my function its return to me With the same number I have documents but the name its different instance of DocumentSnapshot but I need to return same names I have. How can I do this? Below is the code I am using
Widget build(BuildContext context) {
// TODO: implement build
return StreamBuilder < QuerySnapshot > (
stream: Firestore.instance.collection("Institute")
.document(widget.id).collection("Ravs").snapshots(),
builder: (context, snapshot) {
if (snapshot.hasData) {
print('list of docment:${snapshot.data.documents.toList()}');
};
return CircularProgressIndicator();
}
);
}
The Instance of DocumentSnapshot log is saying that you are interacting with the Snapshot object itself. which is what your code is indeed doing.
To get access to the data inside the Snapshot you have to add the .data() call next to your Snapshot, so your stream should look like this:
stream: Firestore.instance.collection("Institute").document(widget.id)
.collection("Ravs").snapshots().data()