# 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: 1. Inisialisasi service notifikasi sejak awal app startup. 2. Channel Android sudah dibuat dengan importance tinggi. 3. Permission notifikasi dan exact alarm diminta secara eksplisit. 4. Scheduling memakai timezone-aware API (zoned schedule). 5. Ada fallback jika exact alarm tidak diizinkan (tetap kirim inexact). 6. Receiver Android untuk scheduled notification + boot completed sudah terpasang. 7. 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](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](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](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](lib/services/panen_runtime_scheduler_service.dart) - Service auto capture panen: [lib/services/panen_auto_capture_service.dart](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](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: 1. Pasang package: - flutter_local_notifications - timezone - flutter_timezone 2. Buat service singleton notifikasi (pola seperti NotificationService). 3. Pada initialize: - init timezone, - init plugin, - create channel Android, - request permission notif + exact alarm. 4. Buat API wrapper: - showInstantNotification - scheduleOneShot - scheduleDaily - cancelByKey - pending list 5. Gunakan stable notification ID berbasis key agar update/cancel tidak salah sasaran. 6. Simpan source of truth jadwal (DB lokal/remote), lalu resync di startup app. 7. Tambahkan debug screen untuk: - test instant notif, - test jadwal 30 detik, - lihat pending schedule, - test exact alarm permission. 8. Tambahkan Android receivers + permission yang diperlukan. 9. Uji di beberapa kondisi device (lihat checklist pengujian di bawah). 10. Jika butuh event server saat app mati, tambahkan FCM backend. ## 6) Checklist Pengujian yang Wajib 1. Foreground test: instant notif muncul. 2. Background test: jadwal 30 detik tetap muncul saat app diminimize. 3. Terminated test: jadwal tetap muncul setelah app diswipe (untuk jadwal yang sudah tercatat). 4. Reboot test: setelah restart HP, jadwal masih ada atau berhasil resync saat app dibuka. 5. Exact alarm off test: pastikan fallback inexact tetap bekerja. 6. Permission denied test: app tidak crash, tampilkan instruksi jelas ke user. 7. OEM aggressive battery test (Xiaomi/Oppo/Vivo, dsb): validasi behavior nyata. ## 7) Batasan Nyata di Android Modern 1. Doze/battery optimization bisa menunda notifikasi non-exact. 2. Exact alarm butuh izin user di banyak device/versi Android. 3. Sebagian vendor membatasi background process dengan agresif. 4. Karena itu, selalu sediakan fallback, status pending, dan edukasi user. ## 8) Rekomendasi Praktis untuk Produksi 1. Pisahkan notifikasi menjadi: - reminder terjadwal (lokal), - event backend (push). 2. Simpan mapping scheduleKey -> bisnis ID secara konsisten. 3. Hindari log print berlebih pada mode produksi. 4. Tambahkan telemetry sederhana (berapa jadwal aktif, terakhir sync kapan). 5. 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.