FlutterFirebase
FlutterFirebase

Reputation: 2353

StreamBuilder using StreamController from Firestore snapshots

I am try load Firestore snapshots() into StreamController so can give to StreamBuilder so can build newsfeed in app.

But get error:

The getter 'stream' was called on null.

The method 'add' was called on null.

Here my code:

StreamController<QuerySnapshot> _localStreamController = StreamController<QuerySnapshot>();

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

Firestore.instance.collection(‘info’).snapshots().listen((QuerySnapshot querySnapshot) {

//      if(userAdded == null) {
        _localStreamController.add(querySnapshot);
//      }

    });
...
child: StreamBuilder(
stream: _localStreamController.stream,
builder: (context, snapshot) {

Anyone know solution? Thanks!

Upvotes: 1

Views: 1930

Answers (2)

ilyes chicha
ilyes chicha

Reputation: 121

Solution #1 :

You need to initialize the stream Replace this line

StreamController<QuerySnapshot> _localStreamController = StreamController<QuerySnapshot>();

with:

StreamController<QuerySnapshot> _localStreamController = StreamController.broadcast();

because broadcast() need to listen to data before requesting it from firebase you need to add listener in the initSatat it will be some thing like this :

  @override
  void initState() {
    // this doesn't have to do any thing  
    _localStreamController.stream.listen((event)=>print(event));
    Firestore.instance.collection('info').snapshots().listen((QuerySnapshot querySnapshot) =>
    _localStreamController.add(querySnapshot));
    super.initState();

  }

and your stream builder look like this :

StreamBuilder(
  stream: _localStreamController.stream,
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      return ...
    } else {
     return CircularProgressIndicator();
    }
  },
)

Solution #2 :

you can loss the controller and stream the data directly in the Stream builder all throw it's not best practice. it will be some thing like this:

StreamBuilder(
  stream: Firestore.instance.collection('info').snapshots(), // <= change
  builder: (context, snapshot) {
    if (snapshot.hasData) {
      return ...
    } else {
     return CircularProgressIndicator();
    }
  },
)

and you don't to use StreamController or initState

Upvotes: 1

StuffDeveloper
StuffDeveloper

Reputation: 81

You need to initialize the stream Replace this line:

StreamController<QuerySnapshot> _localStreamController = StreamController<QuerySnapshot>();

with:

StreamController<QuerySnapshot> _localStreamController = StreamController.broadcast();

Then in your builder, you will want to account for the data not being loaded yet. So showing a loading screen or something could be useful. Something like this:

if (!snapshot.hasData || snapshot.data.documents.length == 0) {
            return Center(child: const Text('Loading ...'));
          }

Upvotes: 0

Related Questions