Count document where value matched in firestore Flutter - firebase

i m getiing 20 comments value but i only enter only two comments on my post i m not finiding this solution. in the above i m using stream builder error is there where i m putting query on my text.
stream builder:
StreamBuilder(
stream: FirebaseFirestore.instance.collection("post").snapshots(),
builder: (BuildContext context,AsyncSnapshot<QuerySnapshot>snapshot){
return ListView.builder(
shrinkWrap: true,
scrollDirection: Axis.vertical,
itemCount: snapshot.data.docs.length,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (_,index) {
return
Text('${FirebaseFirestore.instance.collection("comments").where("postid",isEqualTo:
snapshot.data.docs[index].id).get().toString().length}')
}

You must use the .length on the snapshot's docs property directly as shown below:
final QuerySnapshot snapshot = await Firestore.instance.collection('products').where("postid",isEqualTo: snapshot.data.docs[index].id).get();
final int documents = snapshot.docs.length;
Another way using Future:
FirebaseFirestore.instance
.collection("products")
.where("postid", isEqualTo: snapshot.data.docs[index].id)
.get()
.then((snapshot) => {
print(snapshot.docs.length);
});

so i know the solution of this so i post the example of above problem
StreamBuilder(stream:FirebaseFirestore.instance.collection("comment").where("postid",isEqualTo: snapshot.data.docs[index].id).snapshots(),
builder: (context,projsnap){
final int documents = projsnap.data.docs.length;
return Text('${documents}');
}),

Related

how can orderby array in map firestore with flutter?

return StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection("posting")
.where("authorId", isEqualTo: widget.uid)
//.orderBy("datetime")
.snapshots(),
builder: (context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (!snapshot.hasData) {
return Container();
}
return ListView.builder(
itemCount: snapshot.data!.size,
physics: BouncingScrollPhysics(),
itemBuilder: (context, index) {
//return Container();
return ListView.builder(
shrinkWrap: true,
physics: BouncingScrollPhysics(),
itemCount: snapshot.data!.docs[index["replyCount"],
itemBuilder: (context, count) {
return StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('users')
.where("uid",
isEqualTo: snapshot.data!.docs[index]["reply"]
[count]["replyId"])
.snapshots(),
builder: (context, replyUser) {
for example, user has some posts written by this user.
some other user reply his posting.
then I want to show user who was writing post can be check reply alarm. order by reply time
This won't work:
.orderBy("reply.datetime")
For one, there is no field reply.datetime in your document. There is only reply[0].datetime, but I doubt you can specify an array item like that.
The common use-case for what you're trying to do is to order the documents on their latest reply timestamp. For such cases, the idiomatic approach is to store the timestamp of the latest reply as a top-level field in your document (say latestReplyDateTime) and order on that field.

Get only documents in a FireBase collection that have an id matching with documents in a separate collection

I have the following database structure:
users
|_____user01
|_____groups
|_____0002
|_____0004
|_____0006
groups
|_____0001
|_____0002
|_____0003
|_____0004
|_____0005
|_____0006
I currently have a StreamBuilder() that creates a list with all the entries it finds in root/groups, so it creates a list of 6 elements.
I need it to create a list using the entries in root/groups as it's doing now, but only those that have an id that matches the IDs of entries present in root/users/user01/groups, so it should create a list with 3 elements (0002, 0004 and 0006).
I can't wrap my head around how to achieve that.
This is my StreamBuild() :
StreamBuilder(
stream: FirebaseFirestore.instance.collection("groups").snapshots(),
builder: (context, snapshots) {
if (snapshots.hasData) {
return ListView.builder(
shrinkWrap: true,
itemCount: snapshots.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot documentSnapshot =
snapshots.data.documents[index];
return Dismissable(
child: Card(
)
)
Should I make a firebase query using where() that excludes documents IDs not shared by the two collections and feed the results to the StreamBuilder?
I would recommend you to use a FutureBuilder for every document inside the list you are creating using StreamBuilder and rendering using ListView.builder.
Create a future that matches each and every document in the list with documents inside the sub-collection of user i.e, groups.
Future<bool> matchDocs(String id)async{
final result = await FirebaseFirestore.instance.collection('users').doc(FirebaseAuth.instance.currentUser.uid).collection('groups').doc(id).get();
return result.exists;
}
Inside itemBuilder function return a FutureBuilder.
StreamBuilder(
stream:
FirebaseFirestore.instance.collection("groups").snapshots(),
builder: (context, snapshots) {
if (snapshots.hasData) {
return ListView.builder(
shrinkWrap: true,
itemCount: snapshots.data.documents.length,
itemBuilder: (context, index) {
DocumentSnapshot documentSnapshot =
snapshots.data.documents[index];
return FutureBuilder<bool>(
future: matchDocs(
snapshots.data.documents[index].data()['id'].toString()),
builder: (context, snapshot) {
if (snapshot.hasData) {
if (snapshot.data) {
return Dismissible(key: null, child: null);
}
}
return Container();
}
);
}
);
}
}
)
Note: I did not have any idea about your exact data models, so you
should be careful while implementing this solution.

Flutter Firebase not returning correct queried documents

I want to find all the documents in the 'communities' collection, where the user's id is contained in the 'members' array.
But my firebase query is just returning ALL the documents in the 'communities' collection instead of just the ones I queried.
Stream<QuerySnapshot> get userCommunities {
return communityCollection.where('members', arrayContains: uid).orderBy('lastActive', descending: true).snapshots();
}
...
StreamBuilder(
stream: DBService().userCommunities,
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasData)
return ListView.builder(
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
return ListTile(title: Text(snapshot.data.documents[index]['name']));
});
else
return Container();
},
),
testCommunity2 does not contain the user's id in members but my app displays both communities in the listview
Fixed it! I found that my uid was returning null in return communityCollection.where('members', arrayContains: uid)

Query specific field in Firestore snapshot

I created this stream that gets a snapshot of a specific document. Inside the document theres an array called tripAttractions that I want to build into a list. The question is, how do I access this specific array from the snapshot?
Stream<QuerySnapshot> getAttractions(BuildContext context) async* {
Firestore.instance
.collection('trips')
.document(documentId)
.snapshots(includeMetadataChanges: true);
}
The list shows how I'm trying to access the snapshot tripAttractions data but this doesn't work.
ListView.builder(
itemCount: snapshot.data['tripAttractions'].length,
itemBuilder: (BuildContext context, int index) =>
tripAttractionsCards(
context, index, snapshot.data['tripAttractions']),
);
Array inside the firestore document
Most likely you're just missing the array accessor in the item builder:
ListView.builder(
itemCount: snapshot.data['tripAttractions'].length,
itemBuilder: (BuildContext context, int index) =>
tripAttractionsCards(
context, index, snapshot.data['tripAttractions'][index]),
);
Ok the issue was that incorrectly called QuerySnapshot. I'm supposed to use DocumentSnapshot since I'm calling a document directly. Also I had to add yield* to return the data from firestore.
Stream<DocumentSnapshot> getAttractions(BuildContext context) async* {
yield* Firestore.instance
.collection('trips')
.document(documentId)
.snapshots(includeMetadataChanges: true);
}
I was able to troubleshoot this by checking if the snapshot was sending any data by adding an if statement inside the streamBuilder.
if (!snapshot.hasData) return Text("Loading");

How to display the firebase array in the list view in flutter

Future<List<DocumentSnapshot>> getData() async {
var firestore = Firestore.instance;
QuerySnapshot qn = await firestore
.collection("UserTransactions")
.where("AuthUserId", isEqualTo: userId)
.getDocuments();
return qn.documents;
}
Here I am getting all the documents according to the id, I want to display the transactions which is an array in the List View
FutureBuilder(
future: getData(),
builder: (_, AsyncSnapshot<List<DocumentSnapshot>> snapshot) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (_, index) {
return Text(snapshot.data[index].data["transactions"][index]["Mode"])
})
}
);
I am getting the error:
The getter 'length' was called on null.
Receiver: null
Tried calling: length
How to display those values and also display nothing if the array is blank?
You need to check if data is retrieved all not:
FutureBuilder(
future: getData(),
builder: (_, AsyncSnapshot<List<DocumentSnapshot>> snapshot) {
if(snapshot.hasData){
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (_, index) {
return Text(snapshot.data[index].data["transactions"][index]["Mode"])
}
return CircularProgressIndicator();
}
)
Use snapshot.hasData to check if the data is retrieved and CircularProgressIndicator which will display a loading icon until data is fully retrieved.

Resources