flutter - StreamBuilder ListView在首次加载时从Firestore返回空列表

标签 flutter dart google-cloud-firestore stream-builder

在注册过程中,我正在构建的应用程序中为每个“用户”文档创建了一个子集合,最多包含100个文档。

我正在尝试用StreamBuilder显示这些子集合文档。

我有一个无法解决的奇怪错误。用户首次查看时,StreamBuilder不显示数据。而是返回一个空列表。

我可以看到文档已在子集合中正确生成。正在使用StreamBuilder在页面之前的页面上设置数据。即使存在延迟,我也会以为新文档会刚开始出现在StreamBuilder中。
Firebase console view

如果重新启动应用程序-或者用户注销并再次登录,则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元素-例如仅有一个页面-但这无济于事。

我尝试使用DocumentSnapshotQuerySnapshot访问数据。我两个都有问题。

我敢肯定这很简单,但是坚持下去。任何帮助,不胜感激。谢谢!

最佳答案

不能使用查询快照和文档快照中的任何一个来获取

您应该首先使用Querysnapshot进行查询,然后将信息检索到Documentsnapshot
是的,加载文档可能需要花费几秒钟的时间,因此应该异步并等待功能的解决方案是正确的

建议您使用直接快照,而不要使用streamBuilder

我们可以在statefullWidget的initstate中加载文档快照
当您的类是statefullWidget并且问题也与状态有关时,

...

 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

关于flutter - StreamBuilder ListView在首次加载时从Firestore返回空列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60416064/

相关文章:

node.js - Firestore云函数中通过uid获取auth用户

flutter - Flutter中的setState()方法直到for循环中的最后一次调用才更新 View

flutter - Flutter 可以扩展颜色吗?

flutter - Flutter:如何通过ToggleButtons对ListView进行排序

google-chrome-extension - Dart Chrome 扩展 : Listen to chrome api events

Flutter Web Firestore 错误 : Expected a value of type '((Object?) => Object)?' , 但得到类型 '(Object) => Object?' 之一

dart - Flutter 从 flask 端点响应下载 pdf

ios - Flutter Firebase 回调不会在 iOS 13 上触发,但在 Android 上可以正常工作

即使键相等,Dart 也无法在映射中找到值

swift - 无法在 Firestore 中创建新文档