15

I thought I understood StreamBuilders but I have some doubts that are puzzling me.

I thought that a ConnectionState.waiting means that the connection with the stream is being created so it is not still possible to receive stream data. Nevertheless in my case I am always receiving a ConnectionState.waiting . The first time the data is the data specified in the initialData, which is fine, but after i'm getting values from the stream evnt if the ConnectionState is always "waiting". To show this here you can see the screenshot of the first time the builder function is called. This looks good: the snapshot value is the one provided by the initialData parameter And the ConnectionState is waiting enter image description here

Then this is the screenshot of the second time the builder function is called. enter image description here

Here the snapshot value is a new stream value ( so the connection state should be active by now) BUT actually, the connectionState is still waiting!!

  1. So how should I interpret that? How does that work?

  2. Why does the StreamBuilder keep receiving snapshots even if the connectionState is always waiting? why it is not active?

  3. How can I debug that?

onthemoon
  • 3,302
  • 3
  • 17
  • 24
  • if I don't skip the first element of the stream ( stream: authBloc.state.skip(1) ), then the behaviour of the streamBuilder is correct. Why is that?I don't understand what's going on – onthemoon May 06 '19 at 14:09
  • what's the reason of the downvote? – onthemoon May 06 '19 at 17:16
  • https://stackoverflow.com/questions/61111308/streambuilder-in-flutter-stuck-with-connectionstate-waiting-and-displays-only-th/61113958?noredirect=1#comment108150286_61113958 Check out this thread might help – AdnanAsali Apr 10 '20 at 01:02
  • did you manage to fix this? – anoop4real Apr 11 '20 at 10:41

6 Answers6

1

You need to add listen:false to your provider.

John Joe
  • 12,412
  • 16
  • 70
  • 135
1

This is likely to be your Firestore rules. If it's like this:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth.uid != null;
    }
  }
}

then you'll have t be authenticated to grab the data. You can test this quickly (but not permanently) by allowing access to the DB from anyone ...

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if true;
    }
  }
}

... but please do change it to something more secure afterwards.

Lee Probert
  • 10,308
  • 8
  • 43
  • 70
0

Encountered the same issue. Checking the code, if you passed a not null data, the status will be set to waiting.

If you want to make the status to be 'none', then you need to pass null first and pass the Stream to the StreamBuilder when the data is on fetching. enter image description here

Kokuou
  • 129
  • 2
  • 9
0

I use a stream variable otherwise I would have the same error

 Stream<List<List<User>>> friendUser;
  @override
  Widget build(BuildContext context) {
    final
     db = Provider.of<FirestoreDatabase>(context, listen: false);
    friendUser = StreamZip([db.usersStream1(), db.usersStream2()]);
   return Scaffold(
   ...
      StreamBuilder<List<List<User>>>(
                      stream: friendUser,
                      //qui ont deja discuter
                      initialData: [],
                      builder: (context, snapshot) {...}),

   );

}
mario francois
  • 1,291
  • 1
  • 9
  • 16
0

I had the same problem and it wasn't the fault of the firebase The error was when the summons was requested, it must be from within the state

class _FeaturedProductsState extends State<FeaturedProducts> {
   final Stream<QuerySnapshot> productsStreamFeatured = FirebaseFirestore.instance
       .collection('Products')
       .where('productFeatured', isEqualTo: true)
       .snapshots();
   @override
   Widget build(BuildContext context) {
     return Container();
}
}
Sylvester
  • 96
  • 1
  • 11
-2

I suggest you drop the if/else condition and use a switch to check for the ConnectionState.

switch(snapshot.connectionState){
  case ConnectionState.waiting:
    return Center(child:CircularProgressIndicator());
    break;
  default:
    if(snapshot.hasError){
       // Handle errors
     }else if(!snapshot.hasData){
       // Handle no data
      }else {
       // Check for null
       var result = snapshot.data
       if(result!=null){
         //Handle the null value
       } else {

        }
      }

    break;


}
Blacksmith
  • 712
  • 8
  • 21