我目前使用流构建器和未来构建器同时调用两个集合。我遇到了困难,因为每次数据库更改时流构建器都会刷新。这是我的源代码:
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(),
变量在这里:
final CollectionReference userCollection =
FirebaseFirestore.instance.collection('users');
final FirebaseAuth _auth = FirebaseAuth.instance;
还尝试调用两个流构建器:
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>;
似乎没有更好的方法来调用两个集合,但是通过考虑本文中提到的一些优化步骤,您可以实现更少的重建:
- 只在
中包装在流更改期间应该重建的小部件StreamBuilder
- 使用
Stream.map
将您的流对象映射到您的小部件需要在UI中显示的对象。- 使用
Stream.distinct
来创建_DistinctStream
,以防当流在a中提供相同的值时,您的小部件不应该重新构建行。- 在
initState
上为StreamBuilders
创建一个单独的_DistinctStream
,以便它们可以首先保存流值streamController
在屏幕的第一个值之前流一个新值构建。