import 'dart:async'; import 'dart:convert'; import 'dart:io'; import 'package:diplomaticquarterapp/config/config.dart'; import 'package:diplomaticquarterapp/config/shared_pref_kay.dart'; import 'package:diplomaticquarterapp/core/model/notifications/get_notifications_response_model.dart'; import 'package:diplomaticquarterapp/models/LiveCare/IncomingCallData.dart'; import 'package:diplomaticquarterapp/pages/DrawerPages/notifications/notification_details_page.dart'; import 'package:diplomaticquarterapp/pages/landing/landing_page.dart'; import 'package:diplomaticquarterapp/pages/livecare/incoming_call.dart'; import 'package:diplomaticquarterapp/pages/webRTC/OpenTok/OpenTok.dart'; import 'package:diplomaticquarterapp/uitl/app-permissions.dart'; import 'package:diplomaticquarterapp/uitl/date_uitl.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:firebase_messaging/firebase_messaging.dart' as fir; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; // import 'package:flutter_hms_gms_availability/flutter_hms_gms_availability.dart'; import 'package:flutter_ios_voip_kit/call_state_type.dart'; import 'package:flutter_ios_voip_kit/flutter_ios_voip_kit.dart'; import 'package:huawei_hmsavailability/huawei_hmsavailability.dart'; import 'package:huawei_push/huawei_push.dart' as h_push; import 'app_shared_preferences.dart'; import 'navigation_service.dart'; // |--> Push Notification Background Future backgroundMessageHandler(dynamic message) async { print("Firebase backgroundMessageHandler!!!"); fir.RemoteMessage message_; if (message is h_push.RemoteMessage) { // if huawei remote message convert it to Firebase Remote Message message_ = toFirebaseRemoteMessage(message); h_push.Push.localNotification({h_push.HMSLocalNotificationAttr.TITLE: 'Background Message', h_push.HMSLocalNotificationAttr.MESSAGE: "By: BackgroundMessageHandler"}); } if (message.data != null && (message.data['is_call'] == 'true' || message.data['is_call'] == true)) { _incomingCall(message.data); return; } else { GetNotificationsResponseModel notification = new GetNotificationsResponseModel(); notification.createdOn = DateUtil.convertDateToString(DateTime.now()); notification.messageTypeData = message.data['picture']; notification.message = message.data['message']; await NavigationService.navigateToPage(NotificationsDetailsPage( notification: notification, )); } } // Push Notification Background <--| RemoteMessage toFirebaseRemoteMessage(h_push.RemoteMessage message) { final payload_data = jsonDecode(message.data); final fire_message = RemoteMessage( from: message.from, collapseKey: message.collapseKey, data: payload_data['data'], messageId: message.messageId, sentTime: DateTime.fromMillisecondsSinceEpoch(message.sentTime * 1000), ttl: message.ttl, category: null, messageType: message.type, notification: RemoteNotification( title: message.notification.title, titleLocArgs: (message.notification.titleLocalizationArgs ?? []).map((e) => e.toString()).toList(), titleLocKey: message.notification.titleLocalizationKey, body: message.notification.body, bodyLocArgs: (message.notification.bodyLocalizationArgs ?? []).map((e) => e.toString()).toList(), bodyLocKey: message.notification.bodyLocalizationKey, android: AndroidNotification( channelId: message.notification.channelId, clickAction: message.notification.clickAction, color: message.notification.color, count: null, imageUrl: message.notification.imageUrl.path, link: message.notification.link.path, smallIcon: message.notification.icon, sound: message.notification.sound, ticker: message.notification.ticker, tag: message.notification.tag, ), )); return fire_message; } // callPage(String sessionID, String token, String isWebrtc, String callerIdString) async { callPage(String sessionID, String token) async { // if (isWebrtc == "true"){ // String caller = callerIdString.split("*")[3]; // String receiver = callerIdString.split("*")[4]; // String host = callerIdString.split("*")[5]; // return StartVideoCall(caller: caller, receiver: receiver, iAmCaller: false, host: host); // }else{ await NavigationService.navigateToPage(OpenTokConnectCallPage(apiKey: OPENTOK_API_KEY, sessionId: sessionID, token: token)); // } } _incomingCall(Map data) async { LandingPage.incomingCallData = IncomingCallData.fromJson(data); if (LandingPage.isOpenCallPage == false) { LandingPage.isOpenCallPage = true; final permited = await AppPermission.askVideoCallPermission(currentContext); if (permited) await NavigationService.navigateToPage(IncomingCall(incomingCallData: LandingPage.incomingCallData)); LandingPage.isOpenCallPage = false; } await Future.delayed(Duration(milliseconds: 500)); await AppSharedPreferences().remove('call_data'); } class PushNotificationHandler { final BuildContext context; static PushNotificationHandler _instance; final voIPKit = FlutterIOSVoIPKit.instance; HmsApiAvailability hmsApiAvailability; Timer timeOutTimer; bool isTalking = false; var data = { "AppointmentNo": "2016059247", "ProjectID": "15", "NotificationType": "10", "background": "0", "doctorname": "Call from postman", "clinicname": "LIVECARE FAMILY MEDICINE AND GP", "speciality": "General Practioner", "appointmentdate": "2022-01-19", "appointmenttime": "12:10", "PatientName": "Testing", "session_id": "1_MX40NjIwOTk2Mn5-MTY1NDE2NDQxMjc2Mn5xc3NCZkNIejJOdzgzTkg2TmlXblhQdnl-fg", "token": "T1==cGFydG5lcl9pZD00NjIwOTk2MiZzaWc9MTliNTA3NDAxYmU0MjI5OGY5NTcxZTdhNzQyMTcyZjRjMjBhNjljZTpzZXNzaW9uX2lkPTFfTVg0ME5qSXdPVGsyTW41LU1UWTFOREUyTkRReE1qYzJNbjV4YzNOQ1prTkllakpPZHpnelRrZzJUbWxYYmxoUWRubC1mZyZjcmVhdGVfdGltZT0xNjU0MTY0NDEzJm5vbmNlPTAuNjM3ODkzNDk4NDQ2NTIxOSZyb2xlPW1vZGVyYXRvciZleHBpcmVfdGltZT0xNjU0MjUwODEzJmluaXRpYWxfbGF5b3V0X2NsYXNzX2xpc3Q9", "DoctorImageURL": "https://image.shutterstock.com/image-vector/sample-stamp-square-grunge-sign-260nw-1474408826.jpg", "callerID": "9920", "PatientID": "1231755", "is_call": "true" }; PushNotificationHandler(this.context) { PushNotificationHandler._instance = this; } static PushNotificationHandler getInstance() => _instance; void _timeOut({ int seconds = 15, }) async { timeOutTimer = Timer(Duration(seconds: seconds), () async { print('🎈 example: timeOut'); final incomingCallerName = await voIPKit.getIncomingCallerName(); voIPKit.unansweredIncomingCall( skipLocalNotification: false, missedCallTitle: '📞 Missed call', missedCallBody: 'There was a call from $incomingCallerName', ); }); } init() async { hmsApiAvailability = new HmsApiAvailability(); // VoIP Callbacks voIPKit.getVoIPToken().then((value) { print('🎈 example: getVoIPToken: $value'); AppSharedPreferences().setString(APNS_TOKEN, value); }); voIPKit.onDidUpdatePushToken = ( String token, ) { print('🎈 example: onDidUpdatePushToken: $token'); AppSharedPreferences().setString(APNS_TOKEN, token); }; voIPKit.onDidReceiveIncomingPush = ( Map payload, ) async { print('🎈 example: onDidReceiveIncomingPush $payload'); _timeOut(); }; voIPKit.onDidRejectIncomingCall = ( String uuid, String callerId, ) { if (isTalking) { return; } print('🎈 example: onDidRejectIncomingCall $uuid, $callerId'); voIPKit.endCall(); timeOutTimer?.cancel(); }; voIPKit.onDidAcceptIncomingCall = ( String uuid, String callerId, ) { print('🎈 example: onDidAcceptIncomingCall $uuid, $callerId'); String sessionID = callerId.split("*")[0]; String token = callerId.split("*")[1]; // String isWebRTC = callerId.split("*")[2]; print("🎈 SessionID: $sessionID"); print("🎈 Token: $token"); voIPKit.acceptIncomingCall(callerState: CallStateType.calling); voIPKit.callConnected(); timeOutTimer?.cancel(); print("🎈 CALL ACCEPTED!!!"); Future.delayed(new Duration(milliseconds: 2000)).then((value) async { print("🎈 Incoming Call!!!"); // callPage(sessionID, token, isWebRTC, callerId); callPage(sessionID, token); }); }; // if (Platform.isAndroid && (!await FlutterHmsGmsAvailability.isHmsAvailable)) { if (Platform.isAndroid) { await hmsApiAvailability.isHMSAvailable().then((value) async { if (value != 0) { final fcmToken = await FirebaseMessaging.instance.getToken(); if (fcmToken != null) onToken(fcmToken); } }); } if (Platform.isIOS) { final permission = await FirebaseMessaging.instance.requestPermission(); if (permission.authorizationStatus == AuthorizationStatus.denied) return; } // 'Android HMS' (Handle Huawei Push_Kit Streams) // if (Platform.isAndroid) { // if (Platform.isAndroid && (await FlutterHmsGmsAvailability.isHmsAvailable)) { // } else { // 'Android GMS or iOS' (Handle Firebase Messaging Streams FirebaseMessaging.instance.getInitialMessage().then((RemoteMessage message) async { print("Firebase getInitialMessage with message : ${message.data.toString()}"); subscribeFCMTopic(); if (Platform.isIOS) await Future.delayed(Duration(milliseconds: 3000)).then((value) { if (message != null) newMessage(message); }); else if (message != null) newMessage(message); }); FirebaseMessaging.onMessage.listen((RemoteMessage message) async { print("Firebase onMessage!!!"); // Utils.showPermissionConsentDialog(context, "onMessage", (){}); // newMessage(message); if (Platform.isIOS) await Future.delayed(Duration(milliseconds: 3000)).then((value) { newMessage(message); }); else newMessage(message); }); FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) async { print("Firebase onMessageOpenedApp!!!"); if (Platform.isIOS) await Future.delayed(Duration(milliseconds: 3000)).then((value) { newMessage(message); }); else newMessage(message); }); FirebaseMessaging.instance.onTokenRefresh.listen((fcm_token) { print("Push Notification onTokenRefresh: " + fcm_token); onToken(fcm_token); }); FirebaseMessaging.instance.getToken(vapidKey: 'BHRJG8sIzcysWxPw3B6xQjz_85nUuCfU6EAmpH18kyUTmB2cj35IdFwCyWSab80SA1v6oBSWVh-p6PcHPw_y00Y').then((String token) { print("Push Notification getToken: " + token); onToken(token); }); FirebaseMessaging.onBackgroundMessage(backgroundMessageHandler); if (Platform.isAndroid) { await hmsApiAvailability.isHMSAvailable().then((value) async { if (value == 0) { h_push.Push.enableLogger(); final result = await h_push.Push.setAutoInitEnabled(true); h_push.Push.onNotificationOpenedApp.listen((message) { newMessage(toFirebaseRemoteMessage(message)); }, onError: (e) => print(e.toString())); h_push.Push.onMessageReceivedStream.listen((message) { newMessage(toFirebaseRemoteMessage(message)); }, onError: (e) => print(e.toString())); h_push.Push.getTokenStream.listen((token) { onToken(token); }, onError: (e) => print(e.toString())); await h_push.Push.getToken(''); h_push.Push.registerBackgroundMessageHandler(backgroundMessageHandler); } }).catchError((err) { print(err); }); } } subscribeFCMTopic() async { print("subscribeFCMTopic!!!"); await FirebaseMessaging.instance.unsubscribeFromTopic('all_hmg_patients').then((value) async { await FirebaseMessaging.instance.subscribeToTopic('all_hmg_patients'); }); } newMessage(RemoteMessage remoteMessage) async { print("Remote Message: " + remoteMessage.data.toString()); if (remoteMessage.data.isEmpty) { return; } if (remoteMessage.data['is_call'] == 'true' || remoteMessage.data['is_call'] == true) { _incomingCall(remoteMessage.data); } else { GetNotificationsResponseModel notification = new GetNotificationsResponseModel(); notification.createdOn = DateUtil.convertDateToString(DateTime.now()); notification.messageTypeData = remoteMessage.data['picture']; notification.message = remoteMessage.data['message']; notification.notificationType = remoteMessage.data["NotificationType"].toString(); if (remoteMessage.data["NotificationType"] == "2") { notification.videoURL = remoteMessage.data["VideoUrl"]; } await NavigationService.navigateToPage(NotificationsDetailsPage( notification: notification, )); } } onToken(String token) async { print("Push Notification Token: " + token); AppSharedPreferences().setString(PUSH_TOKEN, token); DEVICE_TOKEN = token; } onResume() async { var call_data = await AppSharedPreferences().getObject('call_data'); if (call_data != null) { _incomingCall(call_data); } } } /* todo verify all functionality */ // _firebaseMessaging.configure( // // onMessage: (Map message) async { // // // showDialog("onMessage: $message"); // // print("onMessage: $message"); // // print(message); // // print(message['name']); // // print(message['appointmentdate']); // // // // if (Platform.isIOS) { // // if (message['is_call'] == "true") { // // var route = ModalRoute.of(context); // // // // if (route != null) { // // print(route.settings.name); // // } // //s // // Map myMap = new Map.from(mesage); // // print(myMap); // // LandingPage.isOpenCallPage = true; // // LandingPage.incomingCallData = IncomingCallData.fromJson(myMap); // // if (!isPageNavigated) { // // isPageNavigated = true; // // Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: LandingPage.incomingCallData))).then((value) { // // isPageNavigated = false; // // }); // // } // // } else { // // print("Is Call Not Found iOS"); // // } // // } else { // // print("Is Call Not Found iOS"); // // } // // // // if (Platform.isAndroid) { // // if (message['data'].containsKey("is_call")) { // // var route = ModalRoute.of(context); // // // // if (route != null) { // // print(route.settings.name); // // } // // // // Map myMap = new Map.from(message['data']); // // print(myMap); // // if (LandingPage.isOpenCallPage) { // // return; // // } // // LandingPage.isOpenCallPage = true; // // LandingPage.incomingCallData = IncomingCallData.fromJson(myMap); // // if (!isPageNavigated) { // // isPageNavigated = true; // // Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: LandingPage.incomingCallData))).then((value) { // // Future.delayed(Duration(seconds: 5), () { // // isPageNavigated = false; // // }); // // }); // // } // // } else { // // print("Is Call Not Found Android"); // // LocalNotification.getInstance().showNow(title: message['notification']['title'], subtitle: message['notification']['body']); // // } // // } else { // // print("Is Call Not Found Android"); // // } // // }, // onBackgroundMessage: Platform.isIOS ? null : myBackgroundMessageHandler, // onLaunch: (Map message) async { // print("onLaunch: $message"); // // showDialog("onLaunch: $message"); // }, // onResume: (Map message) async { // print("onResume: $message"); // print(message); // print(message['name']); // print(message['appointmentdate']); // // // showDialog("onResume: $message"); // // if (Platform.isIOS) { // if (message['is_call'] == "true") { // var route = ModalRoute.of(context); // // if (route != null) { // print(route.settings.name); // } // // Map myMap = new Map.from(message); // print(myMap); // LandingPage.isOpenCallPage = true; // LandingPage.incomingCallData = IncomingCallData.fromJson(myMap); // if (!isPageNavigated) { // isPageNavigated = true; // Navigator.push(context, MaterialPageRoute(builder: (context) => IncomingCall(incomingCallData: LandingPage.incomingCallData))).then((value) { // isPageNavigated = false; // }); // } // } else { // print("Is Call Not Found iOS"); // } // } else { // print("Is Call Not Found iOS"); // } // }, // );