In the app I'm building as part of the registration process a sub-collection, with up to 100 docs, is created for each 'User' document.
I'm trying to show these sub-collection documents in a StreamBuilder.
I have a curious bug that I can't resolve. The StreamBuilder doesn't display the data when the user first views it. Instead it returns an empty list.
I can see that the documents have been correctly generated within the sub-collection. The data is being set on a page before the page with the StreamBuilder. Even if there were latency I would have thought the new docs would have just started appearing within StreamBuilder.
Firebase console view
The StreamBuilder does display the data as expected if the app is restarted - or if the user logs out and logs in again.
Below is the code I'm using:
Stream<QuerySnapshot> provideActivityStream() {
return Firestore.instance
.collection("users")
.document(widget.userId)
.collection('activities')
.orderBy('startDate', descending: true)
.snapshots();
}
...
Widget activityStream() {
return Container(
padding: const EdgeInsets.all(20.0),
child: StreamBuilder<QuerySnapshot>(
stream: provideActivityStream(),
builder: (BuildContext context,
AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
if(snapshot.data == null) {
return CircularProgressIndicator();
}
if(snapshot.data.documents.length < 1) {
return new Text(
snapshot.data.documents.toString()
);
}
if (snapshot != null) {
print('$currentUser.userId');
}
if (
snapshot.hasData && snapshot.data.documents.length > 0
) {
print("I have documents");
return new ListView(
children: snapshot.data.documents.map((
DocumentSnapshot document) {
return new PointCard(
title: document['title'],
type: document['type'],
);
}).toList(),
);
}
}
)
);
}
Edit: Adding main build as per comment request
@override
Widget build(BuildContext context) {
return DefaultTabController(
length: 3,
child: Scaffold(
appBar: AppBar(
title: Text("Home"),
actions: <Widget>[
],
bottom: TabBar(
tabs: [
Text("Account"),
Text("Activity"),
Text("Links"),
],
),
),
body: TabBarView(
children: [
accountStream(),
activityStream(),
linksStream()
]
)
),
);
}
}
Attempts I've made to solve
I initially thought it was a connection error so created a series of cases based on switch (snapshot.connectionState). I can see that ConnectionState.active = true so thought adding a new document in Firestore might have an effect but does nothing.
I tried the following to make the initial stream constructor asynchronous. It fails to load any data.
Stream<QuerySnapshot> provideActivityStream() async* {
await Firestore.instance
.collection("users")
.document(widget.userId)
.collection('activities')
.orderBy('startDate', descending: true)
.snapshots();
}
I've tried removing the tabcontroller element - e.g. just having a single page - but that doesn't help either.
I've tried accessing the data using both a DocumentSnapshot and a QuerySnapshot. I have the problem with both.
I'm sure this is very straightforward but stuck on it. Any help greatly appreciated. Thanks!