简体   繁体   中英

Flutter: StreamBuilder stream not updating

My StreamBuilder didn't refresh after changes to the stream, and also the stream does not update too, when fetching data from Firebase and store it to local SQLite database;

And here is my code for listen to data changes from Firebase and then write those new chats to local :

    /// 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()!,
            conflictAlgorithm: sql.ConflictAlgorithm.replace,
          );
      // Fetch posts
      firestore.fetchPostsStream(chatRoomId).listen((event) async {
        for (QueryDocumentSnapshot post in event.docs) {
          _database.insert(
            'Posts',
            post.data()!,
            conflictAlgorithm: sql.ConflictAlgorithm.replace,
          );
        }
      });

And here the code for fetching data from the Local SQLite database :

/// 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',
        where: 'chatRoomId = ?',
        whereArgs: [chatRoomId],
     ).asStream(), // Returns the stream of the Posts Table in local databases
      _database.query(
        'Calls',
        where: 'chatRoomId = ?',
        whereArgs: [chatRoomId],
       ).asStream(), // Returns the stream of the Calls Table in local databases
      (List<Map<String, dynamic>> streamingMessages,
          List<Map<String, dynamic>> streamingPosts,
          List<Map<String, 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;
      },
    );
  }

The expected timeline when sent a new message will be:

User sent a message --> trigger changes in Firebase --> trigger the LOCAL SQLite to add new data --> Because our SQLite have added new chats, so our ChatScreen should refresh & also a new debug message: 'MySqlite: chat stream changes.' should be printed out again in the console since the ChatScreen is listening to the SQLite Database Stream.

But the actual result is:

User sent a message --> trigger changes in Firebase successfully --> but I DIDN'T see the screen being refreshed NOR new debug message in the console...

I've been struggle with this issue for days, and I don't know why the result is not what I want, if I let the ChatScreen to directly listen to Firebase, it works! *

UPDATE:

I just found out that if I rebuild the ChatScreen (pop the screen, and then open it again), or setState when sending a new message, I can see the new message, it proves that the Message did go into the SQLite database after sent, but it just did not trigger the StreamBuilder. So it might be something wrong with the Fetching Stream.

ANSWER:

I just found out that the SQLite.query function cannot be fetched as a Stream, and I thought I can by using "asStream" method, but this does not do anything, it is a missed feature that SQLite package didn't implement yet, so I add the sqlbrite package that works as a wrapper of the original SQLite package, and it has some additional feature such as querying data as a Stream. ^_^

I just found out that the SQLite.query function cannot be fetched as a Stream, and I thought I can by using "asStream" method, but this does not do anything, it is a missed feature that SQLite package didn't implement yet, so I add the sqlbrite package that works as a wrapper of the original SQLite package, and it has some additional feature such as querying data as a Stream. ^_^

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM