Как поместить данные в 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.