# 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.
