6.6 KiB
Catatan Lengkap Implementasi Notifikasi (TelurKu)
Dokumen ini menjelaskan kenapa sistem notifikasi saat ini berjalan lancar, bagaimana konsep kerjanya, batasannya saat app di-minimize/ditutup, dan apa saja yang perlu dibuat jika ingin dipakai ulang di aplikasi berikutnya.
1) Ringkasan Kenapa Notifikasi Bisa Berjalan Lancar
Sistem notifikasi berjalan baik karena ada kombinasi yang benar antara:
- Inisialisasi service notifikasi sejak awal app startup.
- Channel Android sudah dibuat dengan importance tinggi.
- Permission notifikasi dan exact alarm diminta secara eksplisit.
- Scheduling memakai timezone-aware API (zoned schedule).
- Ada fallback jika exact alarm tidak diizinkan (tetap kirim inexact).
- Receiver Android untuk scheduled notification + boot completed sudah terpasang.
- ID notifikasi harian dibuat stabil dari scheduleKey sehingga update/cancel konsisten.
2) Arsitektur Notifikasi Saat Ini (di Project Ini)
2.1 Service Utama
- Service utama: lib/services/notification_service.dart
- Fungsi penting:
- initialize: setup timezone, init plugin, channel, permissions
- showInstantNotification: kirim notifikasi langsung
- scheduleNotification: jadwalkan notifikasi sekali jalan
- scheduleDailyNotificationAtTime: jadwal harian (repeat per jam yang sama)
- cancelScheduledNotification/cancelAll/pendingNotifications
2.2 Titik Inisialisasi App
- Inisialisasi dipanggil di startup app non-web: lib/main.dart
- Bagian bootstrap juga:
- memuat data awal,
- sinkron jadwal aktif,
- menjadwalkan ulang notifikasi harian,
- cancel jadwal yang tidak aktif lagi.
2.3 Trigger Notifikasi dari Data Realtime
- Realtime listener panen: lib/providers/panen_provider.dart
- Saat ada record baru Firebase Realtime DB, app membuat notifikasi ringkasan panen (pagi/sore).
2.4 Trigger Otomatis Berdasarkan Jam Panen
- Runtime scheduler 30 detik: lib/services/panen_runtime_scheduler_service.dart
- Service auto capture panen: lib/services/panen_auto_capture_service.dart
- Setelah capture, sistem kirim notifikasi summary per jenis panen.
2.5 Konfigurasi Android yang Wajib
- Manifest: android/app/src/main/AndroidManifest.xml
- Sudah ada:
- receiver scheduled notification
- receiver boot completed
- POST_NOTIFICATIONS
- SCHEDULE_EXACT_ALARM dan USE_EXACT_ALARM
- RECEIVE_BOOT_COMPLETED
3) Perilaku Notifikasi Berdasarkan Kondisi App
3.1 App Foreground
- Notifikasi langsung (instant) akan muncul sesuai konfigurasi plugin/channel.
3.2 App Minimize / Background
- Notifikasi terjadwal tetap bisa tampil jika sudah dijadwalkan sebelumnya.
- Ini karena alarm dikelola oleh OS, bukan loop UI Flutter.
3.3 App Ditutup User (swipe away / terminate proses)
- Notifikasi lokal terjadwal yang sudah terdaftar umumnya tetap bisa tampil.
- Tetapi proses Flutter berhenti, artinya:
- listener realtime Firebase berhenti,
- runtime scheduler internal berhenti,
- logic yang butuh eksekusi Dart real-time tidak jalan lagi.
3.4 App Baru Dinyalakan Ulang / Device Reboot
- Dengan boot receiver, jadwal plugin bisa dipulihkan (tergantung platform/plugin).
- Tetap bagus jika app melakukan resync jadwal saat startup (sudah dilakukan di bootstrap).
4) Hal Penting: Notifikasi Lokal vs Push Notification
Notifikasi lokal
Cocok untuk:
- reminder berbasis waktu yang sudah diketahui,
- alarm harian,
- notifikasi yang bisa dijadwalkan dari dalam app.
Keterbatasan:
- tidak ideal untuk event server real-time saat app benar-benar mati total.
Push notification (FCM/APNs)
Diperlukan jika kamu ingin:
- kirim notif dari server kapan pun,
- user tetap menerima event baru meskipun app tidak aktif.
Kesimpulan praktis:
- Reminder waktu tetap: lokal notification.
- Event dari backend/sensor saat app tidak aktif: push notification.
5) Konsep Implementasi Ulang ke App Berikutnya
Urutan implementasi yang direkomendasikan:
- Pasang package:
- flutter_local_notifications
- timezone
- flutter_timezone
- Buat service singleton notifikasi (pola seperti NotificationService).
- Pada initialize:
- init timezone,
- init plugin,
- create channel Android,
- request permission notif + exact alarm.
- Buat API wrapper:
- showInstantNotification
- scheduleOneShot
- scheduleDaily
- cancelByKey
- pending list
- Gunakan stable notification ID berbasis key agar update/cancel tidak salah sasaran.
- Simpan source of truth jadwal (DB lokal/remote), lalu resync di startup app.
- Tambahkan debug screen untuk:
- test instant notif,
- test jadwal 30 detik,
- lihat pending schedule,
- test exact alarm permission.
- Tambahkan Android receivers + permission yang diperlukan.
- Uji di beberapa kondisi device (lihat checklist pengujian di bawah).
- Jika butuh event server saat app mati, tambahkan FCM backend.
6) Checklist Pengujian yang Wajib
- Foreground test: instant notif muncul.
- Background test: jadwal 30 detik tetap muncul saat app diminimize.
- Terminated test: jadwal tetap muncul setelah app diswipe (untuk jadwal yang sudah tercatat).
- Reboot test: setelah restart HP, jadwal masih ada atau berhasil resync saat app dibuka.
- Exact alarm off test: pastikan fallback inexact tetap bekerja.
- Permission denied test: app tidak crash, tampilkan instruksi jelas ke user.
- OEM aggressive battery test (Xiaomi/Oppo/Vivo, dsb): validasi behavior nyata.
7) Batasan Nyata di Android Modern
- Doze/battery optimization bisa menunda notifikasi non-exact.
- Exact alarm butuh izin user di banyak device/versi Android.
- Sebagian vendor membatasi background process dengan agresif.
- Karena itu, selalu sediakan fallback, status pending, dan edukasi user.
8) Rekomendasi Praktis untuk Produksi
- Pisahkan notifikasi menjadi:
- reminder terjadwal (lokal),
- event backend (push).
- Simpan mapping scheduleKey -> bisnis ID secara konsisten.
- Hindari log print berlebih pada mode produksi.
- Tambahkan telemetry sederhana (berapa jadwal aktif, terakhir sync kapan).
- Siapkan halaman troubleshooting notifikasi untuk user.
9) Kesimpulan
Notifikasi di project ini sudah berada di jalur yang benar untuk use-case reminder dan summary lokal. Kunci stabilitasnya ada di setup channel + permission + timezone + scheduler yang disinkronkan ulang saat startup.
Untuk kebutuhan notifikasi real-time ketika app benar-benar mati dan event datang dari server, kamu harus menambahkan arsitektur push notification (FCM/APNs) di sisi backend.