So what is the simplest approach for Caching in Flutter?

After experiencing many solutions for caching, here is what I’ve learned sorted by complexity:

1- using shared preferences 2- using hive db 3- using firestore offline service 4- using sqflite


A simple time-based cache doesn't require much code.

This might help you out. It uses ScopedModel, but it could just as easily be a simple class, although you'd have to either remove the notifyListeners() call or replace it with your own mechanism if you want the model to trigger a refresh of the UI.

class MyModel extends Model{
    Duration _cacheValidDuration;
    DateTime _lastFetchTime;
    List<MyRecord> _allRecords;



    MyModel(){
        _cacheValidDuration = Duration(minutes: 30);
        _lastFetchTime = DateTime.fromMillisecondsSinceEpoch(0);
        _allRecords = [];
    }



    /// Refreshes all records from the API, replacing the ones that are in the cache.
    /// Notifies listeners if notifyListeners is true.
    Future<void> refreshAllRecords(bool notifyListeners) async{
        _allRecords = await MyApi.getAllRecords(); // This makes the actual HTTP request
        _lastFetchTime = DateTime.now();
        if( notifyListeners ) this.notifyListeners();
    }


    /// If the cache time has expired, or forceRefresh is true, records are refreshed from the API before being returned.
    /// Otherwise the cached records are returned.
    Future<List<MyRecord>> getAllRecords({bool forceRefresh = false}) async{
        bool shouldRefreshFromApi = (null == _allRecords || _allRecords.isEmpty || null == _lastFetchTime || _lastFetchTime.isBefore(DateTime.now().subtract(_cacheValidDuration)) || forceRefresh);

        if( shouldRefreshFromApi )
           await refreshAllRecords(false);

        return _allRecords;
    }
}

To get data from MyModel, the UI simply calls getAllRecords(). This will either fetch the records from memory (i.e. from _allRecords) or trigger a refresh which would make a HTTP call and update the records. The cached data automatically expires after 30 minutes, and if you want to force a refresh (for example if the user explicitly taps a refresh button), you can pass forceRefresh: true.

Tags:

Dart

Flutter