[英]StreamController with Firestore
I want to user a StreamController
to control a StreamBuilder
that gets data from a collection in Firestore
. 我想使用
StreamController
来控制从Firestore
的集合获取数据的StreamBuilder
。 This will enable me to use a RefereshIndicator
so that when I pull down on the list, it refreshes/ fetches more data if there is any. 这将使我能够使用
RefereshIndicator
以便在下拉列表时刷新/获取更多数据(如果有)。
I used most of the information in this article . 我最常用的信息,这文章 。 My current code is below
我当前的代码如下
class _Lists extends State<List> {
StreamController _controller;
final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
@override
void initState() {
_controller = new StreamController();
loadPosts();
super.initState();
}
Future fetchPost() async {
return await .
Firestore.instance.collection(_locationState).snapshots();
}
Future<Null> _handleRefresh() async {
count++;
print(count);
fetchPost().then((res) async {
_controller.add(res);
showSnack();
return null;
});
}
showSnack() {
return scaffoldKey.currentState.showSnackBar(
SnackBar(
content: Text('New content loaded'),
),
);
}
loadPosts() async {
fetchPost().then((res) async {
print(res.document);
_controller.add(res);
return res;
});
}
@override
Widget build(BuildContext context) {
final topBar = AppBar(Title("List"));
bottom: TabBar(
indicatorColor: Colors.blueAccent,
indicatorWeight: 3.0,
//indicatorSize: 2.0,
indicatorPadding:
const EdgeInsets.only(bottom: 10.0, left: 47.0, right:
47.0),
tabs: [
Tab(
child: Image(
image: AssetImage("MyImage1"),
width: 65.0,
height: 65.0,
),
),
Tab(
child: Image(
image: AssetImage("Image2"),
width: 90.0,
height: 90.0,
),
),
],
),
return DefaultTabController(
length: 2,
child: Scaffold(
key: scaffoldKey,
appBar: topBar,
body: StreamBuilder(
stream: _controller.stream,
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasError) {
return Text(snapshot.error);
}
if (snapshot.connectionState == ConnectionState.active) {
List aList = new List();
aList.clear();
for (DocumentSnapshot _doc in snapshot.data.documents) {
Model _add = new Model.from(_doc);
aList.add(_add);
}
return TabBarView(
children: <Widget>[
RefreshIndicator(
onRefresh: _handleRefresh,
child: ListView.builder(
itemCount: aList.length,
itemBuilder: (context, index) {
return Card(aList[index]);
},
),
),
Icon(Icons.directions_transit),
],
);
} else {
return Container(
child: Center(child: CircularProgressIndicator()));
}
})));
}
}
}
The Problem I have with this is I keep getting the error 我的问题是我不断收到错误
flutter: ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY
╞═══════════════════════════════════════════════════════════
flutter: The following NoSuchMethodError was thrown building
StreamBuilder<dynamic>(dirty, state:
flutter: _StreamBuilderBaseState<dynamic,
AsyncSnapshot<dynamic>>#53c04):
flutter: Class '_BroadcastStream<QuerySnapshot>' has no instance getter 'documents'.
flutter: Receiver: Instance of '_BroadcastStream<QuerySnapshot>'
flutter: Tried calling: documents
Any ideas on how to go about using the StreamController
with data from Firestore
? 关于如何将
StreamController
与Firestore
数据一起使用的任何想法?
Keeping a close eye on return types in your IDE will likely help avoid a lot of confusing issues like this. 密切注意IDE中的返回类型可能有助于避免出现许多令人困惑的问题。 Unfortunately, that blog does not indicate any types for the API call, StreamController, or 'res' in the then statement.
不幸的是,该博客未在then语句中指出API调用,StreamController或'res'的任何类型。 Having those types declared will help show what you are working with (at least it does for me in Android Studio).
声明这些类型将有助于显示您正在使用的对象(至少对我而言适用于Android Studio)。 For example in my StreamBuilder with a stream from Firestore, I use
AsyncSnapshot<QuerySnapshot> snapshot
instead of just AsyncSnapshot
. 例如,在具有Firestore流的StreamBuilder中,我使用
AsyncSnapshot<QuerySnapshot> snapshot
而不是AsyncSnapshot
。 This allows the tools in Android Studio to tell me that snapshot.data.documents
is the map from the QuerySnapshot
class. 这使Android Studio中的工具可以告诉我
snapshot.data.documents
是QuerySnapshot
类的映射。 If I don't add the extra type, I can't see that. 如果不添加其他类型,则看不到。
Here is an example of listening to the stream from the Firestore Dart package . 这是一个监听Firestore Dart包中的流的示例。
//Performing a query:
Firestore.instance
.collection('talks')
.where("topic", isEqualTo: "flutter")
.snapshots()
.listen((data: QuerySnapshot) =>
// do stuff here
);
Since you're using the async/await style (also perfectly fine), you'll have the same result that will be inside of .listen((data) =>
. We can follow the documentation/classes to see what types are returned. 由于您使用的是async / await样式(也很好),因此您将获得与
.listen((data) =>
相同的结果。我们可以按照文档/类查看返回的类型。
Firestore.instance.collection(<whatever>).snapshots()
will return Stream<QuerySnapshot>
, so we know that await Firestore.instance.collection(<whatever>).snapshots()
will return QuerySnapshot
. Firestore.instance.collection(<whatever>).snapshots()
将返回Stream<QuerySnapshot>
,因此我们知道await Firestore.instance.collection(<whatever>).snapshots()
将返回QuerySnapshot
。
Digging further into the class, we see it has a property called documents
. 进一步研究该类,我们看到它具有一个称为
documents
的属性。
/// Gets a list of all the documents included in this snapshot
final List<DocumentSnapshot> documents;
This finally gives us those DocumentSnapshot
s, which you'll have to pull the data
property from. 最终,我们得到了那些
DocumentSnapshot
,您必须从中提取data
属性。
So in your case, I believe the res
type being QuerySnapshot
will help show you what data to put in your stream, which can be done multiple ways at this point. 因此,在您的情况下,我相信
res
类型为QuerySnapshot
可以帮助您显示要在流中放入哪些数据,这可以通过多种方式完成。 List<DocumentSnapshot>
seems to look like what you're going for, but you could go farther to List<YourClass>
built from the DocumentSnapshot
data
property. List<DocumentSnapshot>
看起来像您想要的东西,但是您可以更进一步了解通过DocumentSnapshot
data
属性构建的List<YourClass>
。 With that, you can say what data type your StreamController will return, making the builder's AsyncSnapshot<your stream type>
much more clear to work with. 这样,您可以说出StreamController将返回哪种数据类型,从而使构建器的
AsyncSnapshot<your stream type>
更加清晰AsyncSnapshot<your stream type>
。
I'm not sure what development tools you are using, but in case you aren't familiar most will allow you to do something like: press/hold (command or ctrl), hover over the type/class/function/var you want to see, left click, and you should be taken to the source files/declarations (I find this super handy). 我不确定您使用的开发工具是什么,但是如果您最不熟悉,将允许您执行以下操作:按下/按住(命令或Ctrl),将鼠标悬停在所需的类型/类/函数/变量上要查看,请单击鼠标左键,然后您将被带到源文件/声明(我觉得这很方便)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.