TIF_E41221079/lib/core/service/fcm_service.dart

128 lines
4.6 KiB
Dart

// lib/core/service/fcm_service.dart
import 'dart:convert';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:smpn1_lengkong/core/routes/app_routes.dart';
import 'package:smpn1_lengkong/main.dart';
import 'package:smpn1_lengkong/core/service/student_service.dart';
// WAJIB: Fungsi ini mesti di luar class untuk handle notif saat aplikasi mati (Terminated)
@pragma('vm:entry-point')
Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async {
debugPrint("Handling a background message: ${message.messageId}");
// Anda boleh tambah logik simpan data ke local storage di sini jika perlu
}
class FcmService {
final _firebaseMessaging = FirebaseMessaging.instance;
final _localNotifications = FlutterLocalNotificationsPlugin();
final _androidChannel = const AndroidNotificationChannel(
'high_importance_channel',
'High Importance Notifications',
description: 'This channel is used for important notifications.',
importance: Importance.max,
playSound: true, // Pastikan ini true
enableVibration: true,
);
Future<void> initNotifications() async {
// Minta Izin User
NotificationSettings settings = await _firebaseMessaging.requestPermission(
alert: true,
badge: true,
sound: true,
);
if (settings.authorizationStatus == AuthorizationStatus.authorized) {
// Dapatkan Token untuk keperluan push dari website/backend
String? token = await _firebaseMessaging.getToken();
debugPrint("FCM Token: $token");
}
// Setup Notifikasi Lokal untuk Foreground
const androidSettings = AndroidInitializationSettings('@mipmap/ic_launcher');
const iosSettings = DarwinInitializationSettings();
await _localNotifications.initialize(
const InitializationSettings(android: androidSettings, iOS: iosSettings),
onDidReceiveNotificationResponse: (NotificationResponse response) {
if (response.payload != null) {
final message = RemoteMessage.fromMap(jsonDecode(response.payload!));
_handleMessage(message);
}
},
);
final platform = _localNotifications.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>();
await platform?.createNotificationChannel(_androidChannel);
// Listen notif saat aplikasi terbuka (Foreground)
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
final notification = message.notification;
if (notification != null) {
_localNotifications.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: AndroidNotificationDetails(
_androidChannel.id,
_androidChannel.name,
channelDescription: _androidChannel.description,
icon: 'ic_launcher',
importance: Importance.max,
priority: Priority.high,
),
),
payload: jsonEncode(message.toMap()),
);
}
});
_setupInteractedMessage();
}
// Handle ketika notifikasi diklik (Aplikasi dari mati/background jadi terbuka)
Future<void> _setupInteractedMessage() async {
// 1. Jika aplikasi dalam keadaan TERMINATED
RemoteMessage? initialMessage = await _firebaseMessaging.getInitialMessage();
if (initialMessage != null) {
_handleMessage(initialMessage);
}
// 2. Jika aplikasi dalam keadaan BACKGROUND
FirebaseMessaging.onMessageOpenedApp.listen(_handleMessage);
}
void _handleMessage(RemoteMessage message) async {
final data = message.data;
final type = data['type'];
// Ambil data student (Gunakan StudentService yang sudah ada)
final studentData = await StudentService().getCurrentStudentData();
if (navigatorKey.currentState == null) return;
// Logik Navigasi berdasarkan 'type' data yang dikirim dari website
if (type == 'violation') {
navigatorKey.currentState?.pushNamed(AppRoutes.discipline, arguments: studentData);
} else if (type == 'academic') {
navigatorKey.currentState?.pushNamed(AppRoutes.academic, arguments: studentData);
} else if (type == 'attendance') {
navigatorKey.currentState?.pushNamed(AppRoutes.attendance, arguments: studentData);
} else {
navigatorKey.currentState?.pushNamed(
AppRoutes.notificationDetail,
arguments: {
'title': message.notification?.title ?? 'Pengumuman',
'body': message.notification?.body ?? '',
'date': DateTime.now().toString(),
},
);
}
}
}