我不是指firestore离线持久性,而是一种永久缓存文档的方式,该文档将在关闭数据库连接和应用程序上幸存下来。我想缓存整个文档。
例如,在一个简单的聊天应用中。说对话中有100条消息,用户已经阅读了全部。发送了一条新消息,因此用户打开应用程序以读取新消息。要重新下载Firestore的所有100条消息,您将为您收取100个文档读取的费用。但是,由于用户已经读取并检索了这些内容,因此我希望他们在本地缓存,而不会从数据库中再次读取(因为聊天消息一旦创建就永远不会更改(。我了解分页可能会有所帮助,但我宁愿不再阅读相同的静态文档。
sqflite是此跨平台的最佳选择,还是有更好的选择?
对于聊天应用程序,我通常会跟踪用户已经看到的最后一条消息。如果您显示按时间戳订购的消息,则意味着您需要保留他们所看到的最新消息的时间戳及其文档ID(以防万一有多个具有相同时间戳的文档(。有了这两个信息,您可以使用collection.startAfter(...)
的Firestore要求新文档。
我建议我保存用户在本地登录的最后一次登录,然后使用它来获取他们未收到的消息。这是一个过于简单的示例:
import 'package:cloud_firestore/cloud_firestore.dart';
/// This class represents your method to acess local data,
/// substitute this class for your method to get messages saved in the device
/// I highly recommend sembast (https://pub.dev/packages/sembast)
class LocalStorage {
static Map<String, Message> get savedMessages => {};
static DateTime get lastLogin => DateTime.now();
static void saveAllMessages(Map<String, Message> messages) {}
static void saveLastLogin(DateTime lastLogin) {}
}
class Message {
String text;
String senderId;
DateTime timestamp;
Message.fromMap(Map<String, dynamic> map) {
text = map['text'] ?? 'Error: message has no text';
senderId = map['senderId'];
timestamp = map['timestamp'];
}
Map<String, dynamic> toMap() {
return {
'text': text,
'senderId': senderId,
'timestamp': timestamp,
};
}
}
class User {
DateTime lastLogin;
String uid;
Map<String, Message> messages;
void updateMessages() {
this.messages = LocalStorage.savedMessages;
this.lastLogin = LocalStorage.lastLogin;
/// Listening to changes in the firestore collection
final firestore = Firestore.instance;
final ref = firestore.collection('users/$uid');
final query = ref.where('timestamp', isGreaterThan: this.lastLogin);
query.snapshots().listen((querySnapshot) {
/// Updating messages in the user data
querySnapshot.documents.forEach((doc) {
messages[doc.documentID] = Message.fromMap(doc.data);
});
/// Updating user last login
this.lastLogin = DateTime.now();
/// Saving changes
LocalStorage.saveAllMessages(this.messages);
LocalStorage.saveLastLogin(this.lastLogin);
});
}
}