Stream listen is not called when limit is added in Firestore query in Dart / Flutter
Asked Answered
B

1

0

Stream listen is not called when limit is added in Firestore query in Dart / Flutter

final _startAtTimestamp = Timestamp.fromMillisecondsSinceEpoch(DateTime.parse('2000-01-01 01:01:01.001').millisecondsSinceEpoch);

I have used below code in my initState() function:

@override
void initState() {
    //
    super.initState();

    Future.delayed(Duration(seconds: 1), () async {
      // 
      Stream<QuerySnapshot> xstream = FirebaseFirestore.instance
          .collection('messages')
          .where('encSenderUId', isEqualTo: _loggedInUserId)
          .where('encReceiverUId', isEqualTo: widget.encUId)
          .orderBy('messageId', descending: true)
          .startAt([_startAtTimestamp])
          .limit(1)
          .snapshots();

      xstream.listen((event) {
        //
        print('Hiii, I am listening..');

        //
      }, onDone: () {
        print("Task Done single");
      }, onError: (error) {
        print("Some Error ${error.toString()}");
      });

    });

}

Case 1: If I DO NOT use limit() in query then listen message is printed once when screen is rendered first time and also listen is called when something is changed in Firestore stream (eg. added new document / removed a document).

Case 2: If I use limit() in query then listen message is printed once when screen is rendered first time but listen is NOT called when something is changed in Firestore stream (eg. added new document / removed a document).

I have to use limit() to fetch one document according to set orderBy. I am 100% sure that limit() is not allowing stream to listen any event.

Firestore structure is as:

enter image description here

Kindly suggest how can I use limit with `listen' to fix this issue. Thanks a lot.

Badillo answered 20/6, 2021 at 5:7 Comment(5)
tried to add onError in listen method?Brightman
@Brightman Thanks dear, I have added onDone and onError callback methods with listen but system is not going into any of these 3 listen, onDone and onError methods. I have updated question by adding onDone and onError at the end. Kindly check and suggest me. Thanks.Badillo
Firestore db structure is as awesomescreenshot.com/image/…Badillo
Please include your Firestore structure as a screen shot in the question. Links can break and move and that would make it unavailable to future readers.Gunas
Thanks @Gunas I have added the screenshot of Firestore Structure with the query. BTW do you have any solution of this issue? Kindly share. Thanks.Badillo
O
0

You query (including .limit(1)) is processed FIRST, THEN the listener attached - so you are listening for changes to ONE, and ONLY ONE document. Only changes to THAT DOCUMENT will cause updates. it DOES NOT re-process the query. Are you TRYING to listen for the MOST RECENT document?

Ocular answered 20/6, 2021 at 20:31 Comment(4)
1) If I do not add .limit(1) in query then it returns me 19 documents which are correct but my requirement is to get only One document out of those 19 documents from messages collection.Badillo
2) you are right that snapshot will have only 1 QuerySnapshotObject in both one ` document` or 19 documents case. We will have to process that QuerySnapshotObject further to get one / 19 documents and we can use map on QuerySnapshotObject. It works but adding .limit(1) is returning nothing. Any suggestion will be highly appreciated? Thanks.Badillo
You misunderstand. When you add .limit(1) to the query, the QuerySnapshotObject will only ever contain ONE object, and only changes to that ONE object will trigger an update. Changing ANY other document, or ADDING any documents, WILL NOT trigger an update - just because the query WOULD result in different document when new documents are added DOESN'T MEAN THE LISTENER WILL BE UPDATED. The query selects WHICH documents to listen to, and will listen to ONLY those documents - the query IS NOT RE-RUN.Ocular
The .onSnapshot() listens to the documents selected, NOT to the query.Ocular

© 2022 - 2024 — McMap. All rights reserved.