Flutter 中的 StreamBuilder 卡在 ConnectionState.waiting 中并且只显示加载标记

Posted

技术标签:

【中文标题】Flutter 中的 StreamBuilder 卡在 ConnectionState.waiting 中并且只显示加载标记【英文标题】:StreamBuilder in Flutter stuck with ConnectionState.waiting and displays only the loading mark 【发布时间】:2020-07-21 11:47:59 【问题描述】:

您好,我正在尝试将 Firebase 文档中的数据动态显示到我的 Flutter 中,并在其中使用循环进行渲染,因此我创建了一个 List<Widget> Cards 并向其中添加了包含卡片的函数 makeItem(),然后将它们在一个循环中,所以问题是当我运行代码时,它一直输出print(snapshot.connectionState);ConnectionState.waiting,它应该是异步快照,但它拒绝按要求加载数据,我应该提到数据是当我点击 "Hot reload in android Studio" 时按需要显示。 所以我不知道如何解决这个问题。提前致谢

【问题讨论】:

请选择一个答案并将其标记为“已接受”;我们在这里不使用任何“已解决”。 我刚刚发布了它,它需要 22 小时才能将答案标记为已接受,所以我不得不写下已解决,因为这是许多开发人员处理的错误 您可以花费 22 小时来提供正确的答案,而不是您已经被否决的仅链接答案,它实际上并没有尝试回答问题,而是只有一个 URL。 它为我解决了错误,我按照文档中的说明进行操作,经过几天的试验后它工作了 :) 那么你的问题是什么,朋友? 我没问题;但你的答案有一个。只需查看“答案链接”下方的When to flag an answer as “not an answer”?。希望这能解释它;显然还有改进的余地。 【参考方案1】:

在将 STREAM BUILDER 与 PROVIDER&CHANGE NOTIFIER 一起使用时,我遇到了同样的问题。

返回视图时,应重新分配流本身。

为您的流创建一个 get 函数,并在返回流之前在该函数中重新分配流。这为我解决了加载问题。

【讨论】:

【参考方案2】:

您可以尝试以下方法吗?

class MyList extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return StreamBuilder<QuerySnapshot>(
      stream: _firestore.collection(widget.city).snapshots(),
      builder: (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) 
        if (snapshot.hasError)
          return Text('Error: $snapshot.error');
        switch (snapshot.connectionState) 
          case ConnectionState.waiting: return Center(child: CircularProgressIndicator(backgroundColor: Colors.amber,strokeWidth: 1),),
          default:
            return ListView(
              children: snapshot.data.documents.map((DocumentSnapshot document) 
                return makeItem(
                  pointName: document['name'],
                  huge: document['lastname'],
                  moderate: document['mobileNumber'],
                  none: document['location'],
                  fights: document['job'],
               );
              ).toList(),
           );
        
      ,
    );
  

【讨论】:

感谢您的回复,但没有工作,相同的输出和 o ho reload 显示了结果 可以分享一下makeItem()函数吗?顺便说一句,我建议您返回一个小部件而不是小部件构建功能。它更有效。您可以使用最终参数创建无状态小部件并返回它。 我添加了 makeItem 函数,是的,将小部件作为一个类更有效,它是一个小部件,虽然我会在一个函数中返回它,但现在它变得更大了,但是我相信小部件类不会对 Stream builder 产生任何影响。 好的,我们来做一个简单的测试。你可以尝试只返回一个文本小部件吗?返回 Text(document['name']) 而不是 makeItem 实际上问题出在流生成器上,一旦连接处于活动状态并获取数据,connectionState 为“正在等待”,然后一切正常 1 分钟让我使用文本小部件而不是 makeITem【参考方案3】:

我想我得到了一些东西给你试试这个。它适用于我的模拟器。

List<Widget> cards = [];
  Stream<QuerySnapshot> firebaseStream;

  @override
  void initState() 
    super.initState();
    firebaseStream = Firestore.instance.collection('Hearings').snapshots();
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: SafeArea(
        child: StreamBuilder<QuerySnapshot>(
          stream: firebaseStream,
          builder: (BuildContext context,
              AsyncSnapshot<QuerySnapshot> asyncSnapshot) 
            List<DocumentSnapshot> snapData;

            if (asyncSnapshot.connectionState == ConnectionState.waiting) 
              return Container(
                child: Center(
                  child: CircularProgressIndicator(
                    backgroundColor: Colors.amber,
                    strokeWidth: 1,
                  ),
                ),
              );
             else if (asyncSnapshot.connectionState ==
                ConnectionState.active) 
              snapData = asyncSnapshot.data.documents;
              if (asyncSnapshot.hasData) 
                for (int i = 0; i < snapData.length; i++) 
                  Widget card = Text(snapData[i].data['locationName']);

                  cards.add(card);
                
              
            
            return ListView.builder(
              itemCount: cards.length,
              itemBuilder: (context, index) => cards[index],
            );
          ,
        ),
      ),
    );

我也有坏消息,虽然现在数据正在更新,但它暴露了你的逻辑中的一些缺陷,它复制了数组中的旧条目。你会看到的。不过这应该很容易解决。

【讨论】:

嘿,谢谢你的回复,我试过了,它实际上没有用,所以我尝试在initState之外初始化firestream,它工作了几次并写了ConnectionState.active,然后它失败了再一次和ConnectionState.waiting,实际上真的很有趣,你认为我应该使用Future.delayed(Duration()) 我无法在第 15 次主菜之后仍然接受数据,但我无法在 initState() 中复制它,这对我也有效,哈哈。我想知道问题是否来自其他地方,尽管它会在哪里。至于未来,你必须向我解释为什么你认为你需要使用它,或者提供一些参考建议在这种情况下使用的人的文档,据我所知你不应该这样做。 没问题,非常感谢您的努力。你认为我应该只在一个简单的 get 函数中获取数据,然后在卡上放置一个实时监听器以在 firebase 中更新它吗? 如果这项工作会是一项不错的工作,那么其他人也遇到了与您完全相同的问题。值得一试。 不错的 def 去看看【参考方案4】:

在 StreamBuilder 上使用 stream.cast() 解决了我的问题。

【讨论】:

这更适合作为问题的评论而不是答案,因为它很短。

以上是关于Flutter 中的 StreamBuilder 卡在 ConnectionState.waiting 中并且只显示加载标记的主要内容,如果未能解决你的问题,请参考以下文章

Flutter 中的 StreamBuilder 卡在 ConnectionState.waiting 中并且只显示加载标记

Flutter:Streambuilder - 关闭流

Flutter BLoC:构建()方法中 StreamBuilder 中的 Navigator.pop

StreamBuilder总是在flutter中的print(snapshot.hasData)中返回false

在构建期间调用 setState() 或 markNeedsBuild(),使用 FutureBuilder 中的 Provider 和 Flutter 中的 StreamBuilder

在 Flutter 中从 Firebase FireCloud 接收数据时,StreamBuilder 中的快照代码不会被执行