flutter - StreamBuilder ListView 在首次加载时从 Firestore 返回空列表
问题描述
在我作为注册过程的一部分构建的应用程序中,为每个“用户”文档创建了一个子集合,其中包含多达 100 个文档。
我试图在StreamBuilder
.
我有一个无法解决的奇怪错误。当StreamBuilder
用户第一次查看数据时,它不会显示数据。相反,它返回一个空列表。
我可以看到文档已在子集合中正确生成。数据正在使用 StreamBuilder 的页面之前的页面上设置。即使有延迟,我也会认为新文档会刚刚开始出现在StreamBuilder
.
Firebase 控制台视图
如果应用程序重新启动,或者用户注销并再次登录,StreamBuilder会按预期显示数据。
下面是我正在使用的代码:
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(),
);
}
}
)
);
}
编辑:根据评论请求添加主构建
@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()
]
)
),
);
}
}
我已经尝试解决
我最初以为是连接错误,所以创建了一系列基于switch (snapshot.connectionState)
. 我可以看到,ConnectionState.active = true
因此认为在 Firestore 中添加新文档可能会产生效果,但什么也没做。
我尝试了以下方法来使初始流构造函数异步。它无法加载任何数据。
Stream<QuerySnapshot> provideActivityStream() async* {
await Firestore.instance
.collection("users")
.document(widget.userId)
.collection('activities')
.orderBy('startDate', descending: true)
.snapshots();
}
我试过删除 tabcontroller 元素——例如只有一个页面——但这也无济于事。
我尝试使用 aDocumentSnapshot
和 a访问数据QuerySnapshot
。我两个都有问题。
我敢肯定这很简单,但坚持下去。非常感谢任何帮助。谢谢!
解决方案
它不是通过使用任何一个查询快照和文档快照来获取的
您应该首先使用 Querysnapshot 进行查询,然后将信息检索到 Documentsnapshot 是的,加载文档可能需要几秒钟 解决方案是正确的,您应该使用 async 和 await 函数
我建议你使用 Direct snapshot 而不是 streamBuilder
当您的类是 statefullWidget 并且问题也与状态有关时,我们可以在 statefullWidget 的 initstate 中加载文档快照
...
bool isLoading;
List<DocumentSnapshot> activity =[];
QuerySnapshot user;
@override
void initState() {
print("in init state");
super.initState();
getDocument();
`` }
getDocument() async{
setState(() {
isLoading = true;
});
user= await Firestore.instance
.collection("users")
.document(widget.userId)
.collection('activities')
.orderBy('startDate', descending: true)
.getDocuments();
activity.isEmpty ? activity.addAll(user.documents) : null;
setState(() {
isLoading = false;
});
}
//inside Widget build(BuildContext context) { return Scaffold( in your body
//section of scaffold in the cointainer
Container(
padding: const EdgeInsets.all(20.0),
child: isLoading ?
CircularProgressIndicator(),
:ListView.builder(
itemCount: global.category.length,
itemBuilder: (context, index) {
return PointCard(
title: activity[index].data['title'],
type: activity[index].data['type'],
);//pointcard
}
),//builder
),//container
推荐阅读
- c# - 仅将包含数据的第一列从一个 DataTable 复制到另一个新 DataTable
- java - BLOG 语言成绩差了一小部分
- php - 如何通过正则表达式收集 HTML 链接中的文本?
- python - 解压二进制数据得到需要字符串参数错误
- python - 如何将 python3 manage.py runserver 放入 Bash 脚本中
- html - HTML 视频标签仅显示背景
- selenium - 如何在 Katalon Studio 中获取元素的所有子元素
- kendo-ui - Kendo Grid - 使每行的单元格可动态编辑/不可编辑
- javascript - Cypress TestRunner 通过“cypress.open”在本地工作,但在 Windows Server 2008 上不工作
- java - 如何避免 Java 类的这个帮助方法中的代码重复?