Reputation: 1017
What is the correct way to keep a stream open between screens in Flutter?
For example, if I have a Firestore field (test_field) that I want to update in real-time on two screens, how would I do that? If I create a streambuilder on the first page, the field's data updates in real-time, but when I pass it to the second screen (SubPage), then it only updates on page load:
@override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: _theStream,
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(
child: Text("Loading..."),
);
} else if (snapshot.data.documents.length != 0) {
return SingleChildScrollView(
child: ListView.builder(
physics: ClampingScrollPhysics(),
shrinkWrap: true,
itemCount: snapshot.data.documents.length,
itemBuilder: (BuildContext context, int index) => MainCard(
streamData: snapshot.data.documents[index],
),
MainCard:
class DetailsCard extends StatefulWidget {
DetailsCard({this.streamData});
final streamData;
...
Widget build(BuildContext context) {
Text(widget.streamData.data['test_field'] // This updates in realtime
GestureDetector(
onTap: () {
Navigator.push(
context,
NoFadeRoute(
builder: (context) => SubPage(
streamData: widget.streamData,
),
),
);
},
SubPage:
class SubPage extends StatefulWidget {
SubPage({this.streamData});
final streamData;
...
Widget build(BuildContext context) {
Text(widget.streamData.data['test_field'] // This only updates on page load
Thanks so much in advance!!
Upvotes: 1
Views: 1250
Reputation: 276881
Streams are kept actives when new routes are pushed.
The issue is, when you pushed your new route, you passed to your route the current value instead of the stream itself.
What that means is, the new route does not listen to the stream.
So instead of passing streamData
, pass the Stream
itself and have NoFadeRoute
use StreamBuilder
to listen to the stream.
Upvotes: 2