Flutter:StreamBuilder 流不更新
Flutter: StreamBuilder stream not updating
流更改后我的 StreamBuilder 没有刷新,而且从 Firebase 获取数据并将其存储到本地 SQLite 数据库时流也没有更新;
这是我的代码,用于监听来自 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()!,
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,
);
}
});
这里是 从本地 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',
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;
},
);
}
发送新消息的预期时间线为:
用户发送了一条消息 --> 在 Firebase 中触发更改 --> 触发本地 SQLite 添加新数据 --> 因为我们的 SQLite 添加了新的聊天,所以我们的 ChatScreen 应该刷新 & 也一条新的调试消息:'MySqlite: chat stream changes!' 应该在控制台中再次打印出来,因为 ChatScreen 正在侦听 SQLite 数据库流。
但实际结果是:
用户发送了一条消息 --> 成功触发了 Firebase 中的更改 --> 但我没有看到正在刷新的屏幕,也没有看到控制台中的新调试消息...
这几天一直在纠结这个问题,不知道为什么结果不是我想要的,如果让ChatScreen直接监听Firebase,就可以了! *
更新:
我刚刚发现如果我重新构建ChatScreen(弹出屏幕,然后再次打开),或者在发送新消息时设置状态,我可以看到新消息,证明Message 确实在发送后进入了 SQLite 数据库,但它只是没有触发 StreamBuilder。所以可能是 Fetching Stream 出了问题。
答案:
我刚刚发现 SQLite.query 函数不能作为 Stream 获取,我想我可以通过使用“asStream”方法,但这没有做任何事情,这是 SQLite 遗漏的功能包还没有实现,所以我添加了 sqlbrite package 作为原始 SQLite 包的包装器,它还有一些额外的功能,比如以流的形式查询数据。 ^_^
我刚发现 SQLite.query 函数不能作为流获取,我想我可以通过使用“asStream”方法,但这没有做任何事情,这是 SQLite 遗漏的功能包还没有实现,所以我添加了 sqlbrite package 作为原始 SQLite 包的包装器,它还有一些额外的功能,比如以流的形式查询数据。 ^_^
流更改后我的 StreamBuilder 没有刷新,而且从 Firebase 获取数据并将其存储到本地 SQLite 数据库时流也没有更新;
这是我的代码,用于监听来自 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()!,
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,
);
}
});
这里是 从本地 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',
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;
},
);
}
发送新消息的预期时间线为:
用户发送了一条消息 --> 在 Firebase 中触发更改 --> 触发本地 SQLite 添加新数据 --> 因为我们的 SQLite 添加了新的聊天,所以我们的 ChatScreen 应该刷新 & 也一条新的调试消息:'MySqlite: chat stream changes!' 应该在控制台中再次打印出来,因为 ChatScreen 正在侦听 SQLite 数据库流。
但实际结果是:
用户发送了一条消息 --> 成功触发了 Firebase 中的更改 --> 但我没有看到正在刷新的屏幕,也没有看到控制台中的新调试消息...
这几天一直在纠结这个问题,不知道为什么结果不是我想要的,如果让ChatScreen直接监听Firebase,就可以了! *
更新:
我刚刚发现如果我重新构建ChatScreen(弹出屏幕,然后再次打开),或者在发送新消息时设置状态,我可以看到新消息,证明Message 确实在发送后进入了 SQLite 数据库,但它只是没有触发 StreamBuilder。所以可能是 Fetching Stream 出了问题。
答案:
我刚刚发现 SQLite.query 函数不能作为 Stream 获取,我想我可以通过使用“asStream”方法,但这没有做任何事情,这是 SQLite 遗漏的功能包还没有实现,所以我添加了 sqlbrite package 作为原始 SQLite 包的包装器,它还有一些额外的功能,比如以流的形式查询数据。 ^_^
我刚发现 SQLite.query 函数不能作为流获取,我想我可以通过使用“asStream”方法,但这没有做任何事情,这是 SQLite 遗漏的功能包还没有实现,所以我添加了 sqlbrite package 作为原始 SQLite 包的包装器,它还有一些额外的功能,比如以流的形式查询数据。 ^_^