从 firebase 获取数据后如何将数据放入 Hivedb?并从 Hivedb 访问数据 1 小时?

How to put data to Hivedb after fetching it from the firebase? And access data from Hivedb for 1 hour?

我正在尝试将数据作为临时存储在应用程序中 1 小时。

我正在从 Firestore 获取数据:

static final FirebaseFirestore _firestore = FirebaseFirestore.instance;
Future<List<DocumentSnapshot>> fetchLeaderBoard() async {
  final result =
      await _firestore.collection('users').orderBy('points', descending: true).limit(10).get();
  return result.docs;
}

为了将它存储到 HiveDb,我做了:

class _LeaderBoardState extends State<LeaderBoard> {
  var _repository;
  List<DocumentSnapshot> users;
  Box box;
    
  @override
  void initState() {
    _repository = Repository();
    users = [];
    super.initState();
    openBox();
  }
    
  Future openBox() async {
    var dir = await path_provider.getApplicationDocumentsDirectory();
    Hive.init(dir.path);
    box = await Hive.openBox('leaderBoard');
    return;
  }
    
  Future<void> _fetchUsers() async {
    users = await _repository.fetchLeaderBoard();
    box.put('users',users);
        
    print("HIVE DB : ");
    print(box.get('users'));
  }
}

现在,如何从 Hivedb 获取它持续 1 小时? 1 小时后,应该会再次从 Firestore 中获取数据。

您必须比较 DateTime 才能实现此目的。在读取数据之前,您先读取一小时是否过去。为此,您必须在 hiveDB 中保存上次读取时间。

为此您需要一些 类。这是一个简化的例子:

class Repository {
  final FirebaseApi api = FirebaseApi(); 
  final HiveDatabase database = HiveDatabase();
  
  Future<List<User>> getUsers() async {
    final List<User> cachedUsers = await database.getUsers();
    if(cachedUsers != null) {
      return cachedUsers;
    }
    final List<User> apiUsers = await api.getUsers();
    await database.storeUsers(apiUsers);
    return apiUsers;
  }
  
  
}

class FirebaseApi {
   
  static final FirebaseFirestore _firestore = FirebaseFirestore.instance;
  
  Future<List<User>> getUsers() async {
    final result = await _firestore.collection('users').orderBy('points', descending: true).limit(10).get();
    
    // convert List<DocumentSnapshot> to List<User>
    return result.docs.map((snapshot) {
      return User(
        id: snapshot.id,
        points: snapshot.data()['points'],
      );
    });
  }
}

class HiveDatabase {
  
  Future<List<User>> getUsers() async {
    final DateTime lastUpdated = await _getLastUpdatedTimestamp();
    if(lastUpdated == null) {
      // no cached copy
      return null;
    }
    final deadline = DateTime.now().subtract(Duration(hours: 1));
    if(lastUpdated.isBefore(deadline)) {
      // older than 1 hour
      return null;
    }
    final box = Hive.openBox('leaderboard');
    return box.get('users');
  }

  Future<void> storeUsers(List<User> users) async {
    // update the last updated timestamp
    await _setLastUpdatedTimestamp(DateTime.now());
    // store the users
    final box = Hive.openBox('leaderboard');
    return box.put('users',users);
  }
  
  Future<DateTime> _getLastUpdatedTimestamp() async {
    // TODO get the last updated time out of Hive (or somewhere else)
  }
  
  Future<void> _setLastUpdatedTimestamp(DateTime timestamp) async {
    // TODO store the last updated timestamp in Hive (or somewhere else)
  }
}

class User {
  final String id;
  final int points;
  
  User({this.id, this.points});
}

注意:我没有使用过Hive,所以存储和读取可能会有点变化。

您需要有一个存储库,负责首先检查数据库中的有效数据,如果没有有效的缓存数据,则重定向到 api。当新数据来自 api 时,存储库将告诉数据库存储它。

数据库会跟踪数据存储的日期时间,以检查一小时后数据是否仍然有效。

重要的是数据库和 firebase api 不应该相互感知。他们只知道 User 模型,并且可能知道他们自己的模型。如果 Hive 需要使用其他模型,请在存储之前和读取之后将 User 映射到这些模型。