StreamBuilder in Flutter stuck with ConnectionState.waiting and displays only the loading mark
Asked Answered
B

4

8

Hi I am trying to display the data inside the Firebase documents into my Flutter dynamically where they get rendered using a loop, so I made a List<Widget> Cards and added to it the function makeItem() that contains the cards, and put them inside a loop, so the problem is that when I run the code it outputs print(snapshot.connectionState); as ConnectionState.waiting all the time and it should be async snapshot yet it refuses to load the data as required, I should mention that the data is display as wanted when I hit "Hot reload in Android Studio" . so I don't know how resolve this issue. Thanks in Advance

Bertilla answered 8/4, 2020 at 22:53 Comment(6)
Please select one answer and mark it as "accepted"; we don't use any "solved" on here.Inhabiter
I just posted it, it need 22 hours to mark the answer as accepted so I had to write solved because its an error many developers deal withBertilla
You could spend those 22 hours to provide a proper answer, instead of your already down-voted link-only answer, which doesn't actually attempt to answer the question, but only has one URL.Inhabiter
It solved the error for me, I followed the instructions in the docs and it worked after days of trials :) so whats your problem, friend?Bertilla
I have no problem; but your answer has one. Just see When to flag an answer as “not an answer”? below "Links to an answer". Hope this explains it; there obviously is room for improvement.Inhabiter
Please use FutureBuilder It solved my problem.Vitebsk
S
5

I had the same problem when using STREAM BUILDER with PROVIDER&CHANGE NOTIFIER.

When returning back to the view, one should re-assign the stream itself.

Make a get function for your stream and in that function before returning your stream re-assign the stream. That solved the problem of loading issue for me.

Sulfite answered 14/1, 2021 at 18:47 Comment(2)
Can you give us example? Thank youMccann
Thanks man, such a simple solution and I had been stuck on this since yesterdayBlather
F
2

Can you try the following?

class MyList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return StreamBuilder<QuerySnapshot>(
      stream: _firestore.collection(widget.city).snapshots(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
        if (snapshot.hasError)
          return Text('Error: ${snapshot.error}');
        switch (snapshot.connectionState) {
          case ConnectionState.waiting: return Center(child: CircularProgressIndicator(backgroundColor: Colors.amber,strokeWidth: 1),),
          default:
            return ListView(
              children: snapshot.data.documents.map((DocumentSnapshot document) {
                return makeItem(
                  pointName: document['name'],
                  huge: document['lastname'],
                  moderate: document['mobileNumber'],
                  none: document['location'],
                  fights: document['job'],
               );
              }).toList(),
           );
        }
      },
    );
  }
}
Feudal answered 8/4, 2020 at 23:27 Comment(8)
Thank you for your response but didnt work, the same output and o ho reload displayed the resultsBertilla
Can you share the makeItem() function? Btw, I suggest you to return a widget instead of a widget building function. It is more efficient. You can create a Stateless Widget with final params and return it instead.Feudal
I added the makeItem function, and yes its more efficient to have the widget as a class, it was a small widget I though I will return it in a funcion but now it has gotten bigger, but the widget class wont make any difference on the Stream builder I believe.Bertilla
Ok, lets make a simple test. Can you try just returning a Text widget? return Text(document['name']) instead of makeItemFeudal
actually the problem is with the stream builder and connectionState is "Waiting" once the connection is active and data is fetched then everything is fine 1 min let me do the text widget instead of makeITemBertilla
I will try this return Text(snapshot.data.documents.toString());Bertilla
same result, stuch on loading circleBertilla
My code is more or less identical and I just hang on the waiting state. I think this could be DB rules but I would expect an Error instead.Downstage
P
2

I think I got something for you try this out. It works on my emulator.

List<Widget> cards = [];
  Stream<QuerySnapshot> firebaseStream;

  @override
  void initState() {
    super.initState();
    firebaseStream = Firestore.instance.collection('Hearings').snapshots();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: StreamBuilder<QuerySnapshot>(
          stream: firebaseStream,
          builder: (BuildContext context,
              AsyncSnapshot<QuerySnapshot> asyncSnapshot) {
            List<DocumentSnapshot> snapData;

            if (asyncSnapshot.connectionState == ConnectionState.waiting) {
              return Container(
                child: Center(
                  child: CircularProgressIndicator(
                    backgroundColor: Colors.amber,
                    strokeWidth: 1,
                  ),
                ),
              );
            } else if (asyncSnapshot.connectionState ==
                ConnectionState.active) {
              snapData = asyncSnapshot.data.documents;
              if (asyncSnapshot.hasData) {
                for (int i = 0; i < snapData.length; i++) {
                  Widget card = Text(snapData[i].data['locationName']);

                  cards.add(card);
                }
              }
            }
            return ListView.builder(
              itemCount: cards.length,
              itemBuilder: (context, index) => cards[index],
            );
          },
        ),
      ),
    );

I got bad news too though now that the data is updating it exposed some flaws in your logic its duplicating old entries in your array. You'll see. That should be easy to fix though.

Priggish answered 9/4, 2020 at 4:25 Comment(8)
Hey thank you for your response, I tried it, it didnt work actually, so i trried initializing the firestream outside the initState, it worked for a couple of times and wrote ConnectionState.active , then it failed again and ConnectionState.waiting, its really interesting actually, Do you think I should use Future.delayed(Duration())Bertilla
I cannot reproduce this on my end still accepting data after 15th entree sorry bout it not working in initState() that works for me too lol. I wonder if the problem is coming from somewhere else idk where it would be though. As for the future you would have to explain to me why you think you need to use it or provide some reference to documentation of someone advising to use in such a case to my knowledge you shouldn't have to.Priggish
no problem, thank you very much for your efforts tho appreciate it. do u think I should just fetch the data in a simple get function and then put a realtime listener on the card to update it onChange in firebase?Bertilla
if that work it would be a nice work around other people have been having the exact same problem as you. worth a shot.Priggish
I believe this should be addressed as an issue on github, Flutter's issues on Github or way tooo manyBertilla
I SOLVED codelabs.flutter-io.cn/codelabs/flutter-firebase/index.html#10 THIS SOLVED EVERYTHING, its tricky but works like a charmBertilla
nice def going to check it outPriggish
using snapshot.hasData worked. The Stream builder returns ConnectionState.waiting then ConnectionState.active. It does not return ConnectionState.done. I then check if the snapshot hasdata then build my listview of cards using the list of custom classes.Pedestrianize
K
0

Using stream.cast() on StreamBuilder solved my problem.

Koball answered 7/12, 2021 at 8:4 Comment(1)
This would be better suited to be a comment to the question than an answer because it is very short.Maritzamariupol

© 2022 - 2024 — McMap. All rights reserved.