how can orderby array in map firestore with flutter? - firebase

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.

Related

Count document where value matched in firestore Flutter

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}');
}),

Correct use of Streams with Flutter-Listview

I am trying to display a realtime chat-screen in flutter with with firebase-firestore (equal to the homescreen of whatsapp).
Working: Creating a list of all the contacts "peers". Have a Look at my Listview:
Container(
child: StreamBuilder(
stream:
//FirebaseFirestore.instance.collection('users').snapshots(),
FirebaseFirestore.instance
.collection('users')
.doc(currentUserId)
.collection('peers')
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(themeColor),
),
);
} else {
return ListView.builder(
padding: EdgeInsets.all(10.0),
itemBuilder: (context, index) =>
buildItem(context, snapshot.data.documents[index]),
itemCount: snapshot.data.documents.length,
);
}
},
),
),
not working: Loading specific data for each tile like last message or name. I cant query this at the time of creating my first list (first query returns peer-ids, second returns userdata of a peer-id). My buildItem method consists of another streambuilder, however, as soon as the first streambuilder makes changes, the app freezes.
Widget buildItem(BuildContext context, DocumentSnapshot document) {
return StreamBuilder<DocumentSnapshot>(
stream: FirebaseFirestore.instance
.collection('users')
.doc(document.data()['peerId'])
.snapshots(),
builder: ...
Is this the proper way to nest streams? Simple Listviews are documented quite well, but i couldn't find a good example on this on google. Any help is appreciated.
Try creating your stream just once in initState and pass it onto this method:
//in initState
peersStream = FirebaseFirestore.instance
.collection('users')
.doc(currentUserId)
.collection('peers')
.snapshots(),
Then use stream: peersStream in the StreamBuilder.
Also, it is recommended to use widget-classes over methods for widgets: https://stackoverflow.com/a/53234826/5066615

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)

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.

add an item to ListView.builder flutter firebase

I'm trying to add a header item at the beginning of my list, so here is how I build it using firebase
new Expanded(
child: new StreamBuilder(
stream: Firestore.instance
.collection("users")
.document("dana")
.collection("Channels")
.snapshots(),
builder: (context, snapshot) {
return new ListView.builder(
scrollDirection: Axis.vertical,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) => _buildList(
context, snapshot.data.documents[index]),
);
}),
)
"_buildList" is just the Widget
Widget _buildListItem(BuildContext context, DocumentSnapshot document)
so I'm basically lost, I've no idea how to add another Widget as header
any suggestions?
You could return the "header" widget (the one you want above the listview but still in it) when the list is on index 0:
return new ListView.builder(
scrollDirection: Axis.vertical,
itemCount: snapshot.data.documents.length,
itemBuilder: (context, index) {
if (index == 0) {
return someWidget, // return the widget you want as "header" here
} else {
return _buildList( context, snapshot.data.documents[index-1]),
}
}
);

Resources