从 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
映射到这些模型。
我正在尝试将数据作为临时存储在应用程序中 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
映射到这些模型。