Как поместить данные в Hivedb после их получения из firebase? И получить доступ к данным из Hivedb за 1 час?

Я пытаюсь разместить данные в приложении как временное хранилище на 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.

2 ответа

Решение

Для этого вам понадобится несколько классов. Вот упрощенный пример:

      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, репозиторий сообщает базе данных о необходимости их хранения.

База данных отслеживает дату и время, когда данные были сохранены, чтобы проверить, действительны ли они по прошествии часа.

Важно то, что база данных и api firebase не должны знать друг о друге. Они знают только о модели и, возможно, о своих моделях. Если Hive нужны другие модели для работы, сопоставьте User к этим моделям перед хранением и после прочтения.

Для этого вам нужно будет сравнить DateTime. Перед чтением данных вы читаете, прошел ли один час или нет. Для этого вам нужно будет сохранить время последнего чтения в вашем hiveDB.

Другие вопросы по тегам