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 获取数据。

4

2 回答 2

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 进来时,存储库会告诉数据库存储它。

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

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

于 2020-12-09T08:19:44.950 回答
0

您将不得不比较 DateTime 来实现这一点。在读取数据之前,您会读取一小时是否已经过去。为此,您必须在 hiveDB 中保存上次读取时间。

于 2020-12-06T13:37:46.060 回答