parse_offline_extension

pub package License: MIT

Offline caching extension for Parse Server SDK Flutter.

Adds saveToLocalCache, removeFromLocalCache, loadAllFromLocalCache and related helpers to every ParseObject via a Dart extension — no subclassing required.


Features

  • O(1) lookups — objects are stored as a Map<objectId, json> so every single-item read, existence check, and removal is a hash lookup, not a linear scan.
  • Batch savessaveAllToLocalCache updates the whole map in one write.
  • Auto-migration — upgrades the old List<String> storage format automatically on first read; existing cached data is preserved.
  • Safe serialisation — all json.decode calls are guarded; corrupt entries are skipped rather than crashing the operation.
  • syncLocalCacheWithServer — push cached objects to the server with an optional shouldSync predicate to avoid blindly overwriting newer server data.

Getting started

dependencies:
  parse_server_sdk_flutter: '>=9.0.0 <11.0.0'
  parse_offline_extension: ^1.1.0
import 'package:parse_offline_extension/parse_offline_extension.dart';

The extension methods are then available on every ParseObject instance.


Usage

Save & load a single object

final post = ParseObject('Post')
  ..objectId = 'abc123'
  ..set('title', 'Hello offline');

// Save to local cache
await post.saveToLocalCache();

// Load back by id
final cached = await ParseObjectOffline.loadFromLocalCache('Post', 'abc123');
print(cached?.get<String>('title')); // Hello offline

Load all cached objects for a class

final posts = await ParseObjectOffline.loadAllFromLocalCache('Post');
for (final p in posts) {
  print(p.get<String>('title'));
}

Check existence (O(1))

final exists = await ParseObjectOffline.existsInLocalCache('Post', 'abc123');

Remove from cache

await post.removeFromLocalCache();

Partial update (no full re-encode)

// Returns true if the object was found and updated
final updated = await post.updateInLocalCache({'title': 'Updated title'});

Batch save

// Efficiently saves / updates multiple objects in one storage write
await ParseObjectOffline.saveAllToLocalCache('Post', fetchedPosts);

Sync local → server

// Push all cached objects to the server.
// Pass shouldSync to skip objects that should not overwrite server state.
await ParseObjectOffline.syncLocalCacheWithServer(
  'Post',
  shouldSync: (obj) => obj.get<bool>('isDirty') == true,
);

Clear cache for a class

await ParseObjectOffline.clearLocalCacheForClass('Post');

Get all cached ids

final ids = await ParseObjectOffline.getAllObjectIdsInLocalCache('Post');

Storage format

Objects are persisted via ParseCoreData().getStore() (the same CoreStore used by the Parse SDK) under the key offline_cache_<ClassName>_v2 as a single JSON-encoded Map<String, String> (objectId → full object JSON).

An older List<String> format (key offline_cache_<ClassName>) is automatically migrated to the new format on first access.


Additional information