微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Flutter:StreamBuilder 流未更新

如何解决Flutter:StreamBuilder 流未更新

从 Firebase 获取数据并将其存储到本地 sqlite 数据库时,我的 StreamBuilder 在更改流后没有刷新,并且流也没有更新;

这是我的代码,用于监听来自 Firebase 的数据更改,然后将这些新聊天记录写入本地

    /// LISTEN TO THE STREAM FROM FIREBASE AND THEN WRITE THE NEW MESSAGES TO THE LOCAL DATASE

  // Fetch normal messages
      firestore.fetchMessagesstream(chatRoomId).listen((event) async {
        for (QueryDocumentSnapshot message in event.docs) {
           _database.insert(
            'Messages',message.data()!,conflictAlgorithm: sql.ConflictAlgorithm.replace,);
        }
      });
      // Fetch calls
      firestore.fetchCallsstream(chatRoomId).listen((event) async {
        for (QueryDocumentSnapshot call in event.docs) {
          _database.insert(
            'Calls',call.data()!,);
      // Fetch posts
      firestore.fetchPostsstream(chatRoomId).listen((event) async {
        for (QueryDocumentSnapshot post in event.docs) {
          _database.insert(
            'Posts',post.data()!,);
        }
      });

这里是用于从本地 sqlite 数据库获取数据代码

/// STREAM FOR LISTENING THE CHANGES IN THE LOCAL DATABASE

Rx.combineLatest3(
      _database.query(
       'Messages',where: 'chatRoomId = ?',whereArgs: [chatRoomId],).asstream(),// Returns the stream of the Messages Table in local databases
      _database.query(
        'Posts',// Returns the stream of the Posts Table in local databases
      _database.query(
        'Calls',// Returns the stream of the Calls Table in local databases
      (List<Map<String,dynamic>> streamingMessages,List<Map<String,dynamic>> streamingPosts,dynamic>> streamingCalls) {
        /// VERY IMPORTANT: THE FOLLOWING PRINT STATEMENT WILL BE PRINT OUT EVERYTIME A NEW CHAT ARRIVE
        /// VERY IMPORTANT: THE FOLLOWING PRINT STATEMENT WILL BE PRINT OUT EVERYTIME A NEW CHAT ARRIVE
        /// VERY IMPORTANT: THE FOLLOWING PRINT STATEMENT WILL BE PRINT OUT EVERYTIME A NEW CHAT ARRIVE
        /// VERY IMPORTANT: THE FOLLOWING PRINT STATEMENT WILL BE PRINT OUT EVERYTIME A NEW CHAT ARRIVE
        /// VERY IMPORTANT: THE FOLLOWING PRINT STATEMENT WILL BE PRINT OUT EVERYTIME A NEW CHAT ARRIVE
        print('MysqLite: chat stream changes!');

        final List<dynamic> contents = [...streamingMessages,...streamingPosts,...streamingCalls];

        return contents;
      },);
  }

发送新邮件的预期时间表是:

用户发送消息 --> 触发 Firebase 中的更改 --> 触发 LOCAL sqlite 添加新数据 --> 因为我们的 sqlite 添加了新的聊天记录,所以我们的 ChatScreen 应该刷新以及一个新的调试消息:'MysqLite:聊天流改变!'应该在控制台中再次打印出来,因为 ChatScreen 正在侦听 sqlite 数据库流。

但实际结果是:

用户发送了一条消息 --> 成功触发了 Firebase 中的更改 --> 但我没有看到正在刷新的屏幕或控制台中的新调试消息...

我已经为这个问题苦苦挣扎了好几天,我不知道为什么结果不是我想要的,如果我让 ChatScreen 直接监听 Firebase,它就可以工作! *

更新:

我刚刚发现如果我重建ChatScreen(弹出屏幕,然后再次打开它),或者发送新消息时setState,我可以看到新消息,证明Message确实走了发送后进入 sqlite 数据库,但它只是没有触发 StreamBuilder。所以可能是 Fetching Stream 有问题。

答案:

我刚刚发现 sqlite.query 函数不能作为 Stream 获取,我认为我可以使用“asstream”方法,但这没有任何作用,这是 sqlite 包没有的遗漏功能尚未实现,所以我添加sqlbrite package 作为原始 sqlite 包的包装器,并且它具有一些附加功能,例如将数据作为流查询。 ^_^

解决方法

我刚刚发现 SQLite.query 函数不能作为 Stream 获取,我认为我可以使用“asStream”方法,但这没有任何作用,这是 SQLite 包没有的遗漏功能尚未实现,所以我添加了 sqlbrite package 作为原始 SQLite 包的包装器,并且它具有一些附加功能,例如将数据作为流查询。 ^_^

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。