Reputation: 2353
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
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
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