Reputation: 91
I'm currently using stream builder and future builder to call two collections at the same time. I'm having hard time because the stream builder refreshes every time the database changes. Here's my source code:
body: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('thread')
.orderBy('published-time', descending: true)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(child: CircularProgressIndicator());
} else {
return snapshot.data!.docs.length > 0
? MediaQuery.removePadding(
removeTop: true,
context: context,
child: ListView(
shrinkWrap: true,
children: snapshot.data!.docs.map((DocumentSnapshot postInfo) {
return FutureBuilder<DocumentSnapshot>(
future: userCollection
.doc(postInfo.get('publisher-Id'))
.get(),
My variables are here:
final CollectionReference userCollection =
FirebaseFirestore.instance.collection('users');
final FirebaseAuth _auth = FirebaseAuth.instance;
Also tried calling two streambuilders:
body: StreamBuilder<QuerySnapshot>(
stream: FirebaseFirestore.instance
.collection('thread')
.orderBy('published-time', descending: true)
.snapshots(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return Center(child: CircularProgressIndicator());
} else {
return snapshot.data!.docs.length > 0
? MediaQuery.removePadding(
removeTop: true,
context: context,
child: ListView(
shrinkWrap: true,
children: snapshot.data!.docs
.map((DocumentSnapshot postInfo) {
return StreamBuilder<DocumentSnapshot>(
stream: userCollection
.doc(postInfo.get('publisher-Id'))
.snapshots(),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.done) {
Map<String, dynamic> userInfo =
snapshot.data!.data()
as Map<String, dynamic>;
Upvotes: 1
Views: 419
Reputation: 1420
It doesn't look like there is a better way of calling two collections, but you can achieve less rebuilds by considering some optiomization steps mentioned in this article:
- Only wrap the widget that should rebuild during a stream change inside a
StreamBuilder
- Use the
Stream.map
to map your stream object into an object that your widget needs to show in UI.- Use the
Stream.distinct
to create a_DistinctStream
in case your widget shouldn’t rebuild when the stream provides the same value in a row.- Create a separate
_DistinctStream
forStreamBuilders
oninitState
so that they can save streamed values first if yourstreamController
streams a new value before the screen's first build.
Upvotes: 1