Date: April 7, 2026 Current Phase: Phase 8 (Testing & Bug Fixes) — Continued Previous Log: Day 10 (Weekly schedule fix, history date detail, history sync)
| Task | Description | Status |
|---|---|---|
| FCM integration | Firebase Admin SDK setup and FCM send implementation | ✅ Done |
| Foreground push notification | Receive FCM and display local notification with action buttons | ✅ Done |
| Background push notification | Background isolate handler with local notification + action buttons | ✅ Done |
| Notification action buttons | Taken ✓ / Skip ✗ buttons trigger API and update UI | ✅ Done |
| Undo dose feature | DELETE /dose/undo endpoint + frontend integration | ✅ Done |
| Medication edit cycle fix | cycleType now parsed from active schedule only | ✅ Done |
| Inactive schedule cleanup | Hard delete schedules with no dose_logs references | ✅ Done |
| DB cleanup | Removed test medications and data | ✅ Done |
Added firebase-admin to backend and initialized with service account credentials:
if not firebase_admin._apps:
cred = credentials.Certificate(settings.FIREBASE_CREDENTIALS_PATH)
firebase_admin.initialize_app(cred)
Used pathlib + .env for credential path management to avoid hardcoded absolute paths.
_send_fcm() ImplementationSends data-only FCM messages so Flutter handles notification display with action buttons:
message = messaging.Message(
data={
'schedule_id': schedule_id,
'log_date': datetime.now(timezone.utc).strftime('%Y-%m-%d'),
'medication_name': medication_name,
'type': 'medication_reminder',
},
android=messaging.AndroidConfig(priority='high'),
token=token,
)
Key decision: data-only (no notification field) so Android does not auto-display a system notification, allowing Flutter to show a custom local notification with action buttons instead.
FcmService._handleForegroundMessage converts incoming FCM data into a local notification with Taken ✓ / Skip ✗ buttons:
static Future<void> _handleForegroundMessage(RemoteMessage message) async {
await _showNotificationFromData(
_localNotifications,
message.data,
message.hashCode,
);
}
Extracted _showNotificationFromData as a shared helper used by both foreground and background handlers to avoid duplication.