import 'dart:io'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:mc_common_app/classes/app_state.dart'; import 'package:mc_common_app/main.dart'; import 'package:permission_handler/permission_handler.dart'; abstract class FirebaseMessagingService { Future getFirebaseToken(); Future initializeNotifications(); } class FirebaseMessagingServiceImp implements FirebaseMessagingService { final FlutterLocalNotificationsPlugin flutterLocalNotifications; final FirebaseMessaging firebaseMessaging; FirebaseMessagingServiceImp({required this.firebaseMessaging, required this.flutterLocalNotifications}); @override Future getFirebaseToken() async => await firebaseMessaging.getToken() ?? ""; Future requestPermissions() async { if (Platform.isIOS) { await flutterLocalNotifications.resolvePlatformSpecificImplementation()?.requestPermissions(alert: true, badge: true, sound: true); } else if (Platform.isAndroid) { AndroidFlutterLocalNotificationsPlugin? androidImplementation = flutterLocalNotifications.resolvePlatformSpecificImplementation(); bool? granted = await androidImplementation?.requestNotificationsPermission(); if (granted == false) { await Permission.notification.request(); } } } @override Future initializeNotifications() async { await requestPermissions(); AppState().setDeviceToken = await getFirebaseToken(); AppState().setDeviceType = Platform.isAndroid ? "1" : "2"; await Permission.notification.isDenied.then((bool value) { if (value) { Permission.notification.request(); } }); // initialise the plugin. app_icon needs to be a added as a drawable resource to the Android head project const AndroidInitializationSettings initializationSettingsAndroid = AndroidInitializationSettings('ic_launcher'); DarwinInitializationSettings initializationSettingsDarwin = const DarwinInitializationSettings( requestAlertPermission: true, requestBadgePermission: true, requestCriticalPermission: true, requestProvisionalPermission: true, requestSoundPermission: true, defaultPresentAlert: true, defaultPresentBadge: true, defaultPresentBanner: true, defaultPresentList: true, defaultPresentSound: true, ); final InitializationSettings initializationSettings = InitializationSettings(android: initializationSettingsAndroid, iOS: initializationSettingsDarwin); await flutterLocalNotifications.initialize(initializationSettings, onDidReceiveNotificationResponse: (notificationResponse) {}, ); RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage(); if (initialMessage != null) _handleNotification(initialMessage); FirebaseMessaging.onMessage.listen((RemoteMessage message) { if (message.notification != null) _handleNotification(message); }); FirebaseMessaging.onMessageOpenedApp.listen(_handleNotification); FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler); FirebaseMessaging.instance.onTokenRefresh.listen((String token) async { AppState().setDeviceToken = token; }); } void _onDidReceiveLocalNotification(int id, String? title, String? body, String? payload) async { logger.i(body); } void _handleNotification(RemoteMessage message) async { logger.i(message.notification!.title); logger.i(message.notification!.body); displayNotification(title: message.notification!.title ?? '', body: message.notification!.body ?? ''); } Future displayNotification({required String title, required String body}) async { const AndroidNotificationDetails androidNotificationDetails = AndroidNotificationDetails( "0", 'mowater', channelDescription: 'mowater_notifications', importance: Importance.max, priority: Priority.high, ticker: 'ticker', ); const DarwinNotificationDetails iOSPlatformChannelSpecifics = DarwinNotificationDetails(threadIdentifier: 'thread_id'); const NotificationDetails notificationDetails = NotificationDetails(android: androidNotificationDetails, iOS: iOSPlatformChannelSpecifics); await flutterLocalNotifications.show(0, title, body, notificationDetails, payload: 'item x'); } } @pragma('vm:entry-point') Future backgroundMessageHandler(RemoteMessage message) async { await Firebase.initializeApp(); }