有没有一种简单的方法可以在Flutter中本地缓存Cloud Firestore文档(而不是离线持久性)?

时间:2019-07-07 21:10:17

标签: firebase flutter google-cloud-firestore

我不是在指Firestore离线持久性,而是一种永久缓存文档的方法,该方法将在关闭数据库连接和应用程序后继续存在。我想缓存整个文档。

例如,在一个简单的聊天应用程序中。假设对话中有100条消息,并且用户已经阅读了所有消息。将发送新消息,因此用户打开应用程序以阅读新消息。要从Firestore重新下载所有100条消息,您需要为100篇文档阅读付费。但是由于用户已经读取和检索了这些内容,因此我希望它们在本地缓存,而不是从数据库中再次读取(因为聊天消息一旦创建就永远不会改变)。我知道分页可能会有所帮助,但我宁愿一次阅读同一份静态文档。

SQFlite是此跨平台的最佳选择,还是有更好的选择?

2 个答案:

答案 0 :(得分:1)

对于聊天应用程序,我通常会跟踪用户已经看到的最后一条消息。如果显示按其时间戳排序的消息,则意味着您需要保留他们所看到的最新消息的时间戳及其文档ID(以防万一有多个具有相同时间戳的文档)。有了这两条信息,您就只能使用collection.startAfter(...)向Firestore请求新文档。

答案 1 :(得分:0)

我建议保存用户上次在本地登录设备的时间,然后使用它仅获取他们未收到的消息。 这是一个过于简化的示例:

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);
    });
  }
}