cloud_firestore文档中的此示例使用StreamBuilder
和ConnectionState
的AsyncSnapshot
来处理处于不同状态的流。通过ConnectionState
而不是StreamProvider
访问流时,是否有类似的方法来管理StreamBuilder
?避免它在实际上从Firestore获得文档之前短时间内返回null
的最佳方法是什么?
这是带有StreamBuilder的cloud_firestore文档中的示例:
class BookList extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamBuilder<QuerySnapshot>(
stream: Firestore.instance.collection('books').snapshots(),
builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
if (snapshot.hasError)
return new Text('Error: ${snapshot.error}');
switch (snapshot.connectionState) {
case ConnectionState.waiting: return new Text('Loading...');
default:
return new ListView(
children: snapshot.data.documents.map((DocumentSnapshot document) {
return new ListTile(
title: new Text(document['title']),
subtitle: new Text(document['author']),
);
}).toList(),
);
}
},
);
}
}
我有一个基本的流:
List<AuditMark> _auditMarksFromSnapshot(QuerySnapshot qs) {
return qs.documents.map((DocumentSnapshot ds) {
return AuditMark.fromSnapshot(ds);
}).toList();
}
Stream<List<AuditMark>> get auditMarks {
return Firestore.instance
.collection('_auditMarks')
.snapshots()
.map(_auditMarksFromSnapshot);
}
这可以通过
StreamProvider
访问(这里省略了其他提供程序): void main() async {
runApp(MultiProvider(
providers: [
StreamProvider<List<AuditMark>>(
create: (_) => DatabaseService().auditMarks, ),
],
child: MyApp(),
));
}
我曾尝试以某种方式将
QuerySnapshot
转换为AsyncSnapshot<QuerySnapshot>
,但可能会出错。当然可以像这样给
StreamProvider
一些initialData
-但这很麻烦,容易出错并且可能很昂贵: initialData: <AuditMark>[
AuditMark.fromSnapshot(await Firestore.instance
.collection('_auditMarks')
.orderBy('value')
.getDocuments()
.then((value) => value.documents.first))
...但是我希望有一种更聪明的方法来管理连接状态,并避免它在可以发出文档之前返回null?
最佳答案
我一直在处理这个问题,不想声明initialData
来绕过此问题。
我所做的是创建一个StreamBuilder作为StreamProvider 的子代。
这样我就可以在 StreamProvider中使用StreamBuilder 的snapshot.connectionState
属性。
这是代码: return StreamProvider<List<AuditMark>>.value(
value: DatabaseService().auditMarks,
child: StreamBuilder<List<AuditMark>>(
stream: DatabaseService().auditMarks,
builder: (context, snapshot) {
if (!snapshot.hasError) {
switch (snapshot.connectionState) {
case ConnectionState.none: // if no connection
return new Text(
"Offline!",
style: TextStyle(fontSize: 24, color: Colors.red),
textAlign: TextAlign.center,
);
case ConnectionState.waiting
// while waiting the data, this is where you'll avoid NULL
return Center(child: CircularProgressIndicator());
default:
return ListView.builder(
// in my case I was getting NULL for itemCount
itemCount: logs.length,
itemBuilder: (context, index) {
return LogsTile(log: logs[index]);
},
);
}
}
else {
return new Text(
"Error: ${snapshot.error}",
style: TextStyle(fontSize: 17, color: Colors.red),
textAlign: TextAlign.center,
);
}
}
)
);
关于flutter - 如何使用StreamProvider检查Firestore快照流的ConnectionState?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/61422082/