Lewati ke konten
Mobile Architecture

Offline-First di Flutter: Strategi Sinkronisasi yang Saya Pakai

Cara saya menangani konflik data dan sinkronisasi pada aplikasi Ventri Farm — yang harus tetap berjalan di kandang tanpa sinyal.

Wafik Ulinnuha

Backend Developer

1 menit baca

Aplikasi Ventri Farm dipakai di kandang ayam, jauh dari menara seluler. Sinyal hilang setiap beberapa menit. UX yang menunjukkan loader saat kehilangan koneksi sama dengan tidak bisa dipakai. Solusinya adalah desain offline-first.

Prinsip yang saya pegang

  1. Tulis lokal terlebih dahulu. Setiap aksi user berbentuk record di SQLite, lengkap dengan local_id, created_at, dan flag sync_status.
  2. Server adalah sumber kebenaran final. Lokal hanya cache yang authoritative sampai sinkron berhasil.
  3. Konflik diselesaikan deterministik. Tidak ada dialog "pilih versi mana" untuk operator lapangan.

Skema data lokal

Saya pakai drift (sebelumnya Moor) di Flutter. Setiap tabel domain punya tabel bayangan untuk antrian sinkron:

class FieldEntries extends Table {
  TextColumn get localId => text()();
  TextColumn get serverId => text().nullable()();
  IntColumn get version => integer().withDefault(const Constant(0))();
  TextColumn get payload => text()(); // JSON
  IntColumn get syncStatus => intEnum<SyncStatus>()();
  DateTimeColumn get updatedAt => dateTime()();

  @override
  Set<Column> get primaryKey => {localId};
}

Strategi resolusi konflik

Untuk Ventri, kebanyakan entitas adalah append-only (catatan kejadian). Konflik nyata jarang terjadi. Untuk yang mutable (master data ayam), saya pakai Last-Write-Wins berdasarkan vector clock sederhana: server menyimpan version yang naik setiap update, dan klien wajib mengirim If-Match versi terakhir yang dikenalnya. Server menolak update jika versi sudah lebih baru, dan klien diminta merge ulang.

Background sync

Saya tidak memaksa sync di main isolate. Worker terpisah berjalan setiap 30 detik (saat foreground) atau dipicu oleh workmanager setiap 15 menit (background). Antrian adalah FIFO, tapi saya batch maksimal 50 record per request agar payload tetap waras saat 4G muncul.

Apa yang akan saya lakukan berbeda

  • Pakai CRDT (seperti Automerge) sejak awal untuk entitas yang collaborative. Tapi untuk single-operator-per-record, LWW sederhana sudah cukup.
  • Lebih agresif dalam metric sinkronisasi: berapa lama record duduk di antrian? Berapa rasio konflik? Tanpa angka ini, sulit memutuskan optimasi.

Offline-first bukan fitur tambahan. Ia mengubah cara kita memikirkan domain model. Investasinya nyata, tapi return-nya juga nyata: aplikasi yang tidak menyalahkan operator karena WiFi-nya hilang.

Topik

#Mobile #Architecture

Bagikan

Kembali ke daftar blog

Bacaan lanjutan

Bacaan lanjutan