857 lines
32 KiB
Dart
857 lines
32 KiB
Dart
import 'dart:convert';
|
||
import 'dart:io';
|
||
import 'package:Intaleq/controller/functions/encrypt_decrypt.dart';
|
||
import 'package:firebase_messaging/firebase_messaging.dart';
|
||
import 'package:flutter/material.dart';
|
||
import 'package:get/get.dart';
|
||
import 'package:http/http.dart' as http;
|
||
import 'package:Intaleq/controller/functions/toast.dart';
|
||
import 'package:Intaleq/views/widgets/elevated_btn.dart';
|
||
|
||
import '../../constant/api_key.dart';
|
||
import '../../constant/box_name.dart';
|
||
import '../../constant/colors.dart';
|
||
import '../../constant/links.dart';
|
||
import '../../constant/style.dart';
|
||
import '../../constant/table_names.dart';
|
||
import '../../env/env.dart';
|
||
import '../../main.dart';
|
||
import '../../print.dart';
|
||
import '../../views/Rate/rate_captain.dart';
|
||
import '../../views/home/map_page_passenger.dart';
|
||
import '../../views/home/profile/promos_passenger_page.dart';
|
||
import '../auth/google_sign.dart';
|
||
import '../functions/audio_record1.dart';
|
||
import '../home/map_passenger_controller.dart';
|
||
import 'access_token.dart';
|
||
import 'local_notification.dart';
|
||
|
||
class FirebaseMessagesController extends GetxController {
|
||
final fcmToken = FirebaseMessaging.instance;
|
||
|
||
List<String> tokens = [];
|
||
List dataTokens = [];
|
||
late String driverID;
|
||
late String driverToken;
|
||
NotificationSettings? notificationSettings;
|
||
|
||
Future<void> getNotificationSettings() async {
|
||
// Get the current notification settings
|
||
NotificationSettings? notificationSettings =
|
||
await FirebaseMessaging.instance.getNotificationSettings();
|
||
'Notification authorization status: ${notificationSettings.authorizationStatus}';
|
||
|
||
// Call the update function if needed
|
||
update();
|
||
}
|
||
|
||
Future<void> requestFirebaseMessagingPermission() async {
|
||
FirebaseMessaging messaging = FirebaseMessaging.instance;
|
||
|
||
// Check if the platform is Android
|
||
if (Platform.isAndroid) {
|
||
// Request permission for Android
|
||
await messaging.requestPermission();
|
||
} else if (Platform.isIOS) {
|
||
// Request permission for iOS
|
||
NotificationSettings settings = await messaging.requestPermission(
|
||
alert: true,
|
||
announcement: true,
|
||
badge: true,
|
||
carPlay: true,
|
||
criticalAlert: true,
|
||
provisional: false,
|
||
sound: true,
|
||
);
|
||
messaging.setForegroundNotificationPresentationOptions(
|
||
alert: true, badge: true, sound: true);
|
||
}
|
||
}
|
||
|
||
NotificationController notificationController =
|
||
Get.isRegistered<NotificationController>()
|
||
? Get.find<NotificationController>()
|
||
: Get.put(NotificationController());
|
||
|
||
Future getTokens() async {
|
||
String? basicAuthCredentials =
|
||
await storage.read(key: BoxName.basicAuthCredentials);
|
||
var res = await http.post(
|
||
Uri.parse(AppLink.getTokens),
|
||
headers: {
|
||
'Authorization':
|
||
'Basic ${base64Encode(utf8.encode(AK.basicAuthCredentials))}',
|
||
},
|
||
body: {},
|
||
);
|
||
var jsonResponse = jsonDecode(res.body);
|
||
if (jsonResponse['status'] == 'success') {
|
||
dataTokens = jsonResponse['data'];
|
||
for (var i = 0; i < dataTokens.length; i++) {
|
||
tokens.add(jsonResponse['data'][i]['token']);
|
||
}
|
||
box.write(BoxName.tokens, tokens);
|
||
} else {
|
||
Get.defaultDialog(title: "Warning", middleText: "Server Error");
|
||
}
|
||
}
|
||
|
||
Future getToken() async {
|
||
fcmToken.getToken().then((token) {
|
||
// Log.print('fcmToken: ${token}');
|
||
box.write(BoxName.tokenFCM, (token.toString()));
|
||
});
|
||
|
||
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
|
||
// If the app is in the background or terminated, show a system tray message
|
||
RemoteNotification? notification = message.notification;
|
||
AndroidNotification? android = notification?.android;
|
||
// if (notification != null && android != null) {
|
||
if (message.data.isNotEmpty && message.notification != null) {
|
||
fireBaseTitles(message);
|
||
}
|
||
});
|
||
FirebaseMessaging.onBackgroundMessage((RemoteMessage message) async {
|
||
// Handle background message
|
||
if (message.data.isNotEmpty && message.notification != null) {
|
||
fireBaseTitles(message);
|
||
}
|
||
});
|
||
|
||
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
|
||
if (message.data.isNotEmpty && message.notification != null) {
|
||
fireBaseTitles(message);
|
||
}
|
||
});
|
||
}
|
||
|
||
Future<void> fireBaseTitles(RemoteMessage message) async {
|
||
if (message.notification!.title! == 'Order'.tr) {
|
||
Log.print('message: ${message}');
|
||
if (Platform.isAndroid) {
|
||
notificationController.showNotification(
|
||
'Order'.tr, message.notification!.body!, 'Order');
|
||
}
|
||
} else if (message.notification!.title! == 'Accepted Ride') {
|
||
if (Platform.isAndroid) {
|
||
notificationController.showNotification(
|
||
'Accepted Ride'.tr, 'Driver Accepted the Ride for You'.tr, 'ding');
|
||
}
|
||
var passengerList = message.data['passengerList'];
|
||
|
||
var myList = jsonDecode(passengerList) as List<dynamic>;
|
||
Log.print('myList: ${myList}');
|
||
final controller = Get.find<MapPassengerController>();
|
||
controller.driverId = myList[0].toString();
|
||
// assume rideId lives at index 2 in your list:
|
||
controller.rideId = myList[3].toString();
|
||
|
||
controller
|
||
..statusRide = 'Apply'
|
||
..isSearchingWindow = false
|
||
..update();
|
||
await controller.rideAppliedFromDriver(true);
|
||
|
||
// driverAppliedTripSnakBar();
|
||
} else if (message.notification!.title! == 'Promo'.tr) {
|
||
if (Platform.isAndroid) {
|
||
notificationController.showNotification(
|
||
'Promo', 'Show latest promo'.tr, 'promo');
|
||
}
|
||
Get.to(const PromosPassengerPage());
|
||
} else if (message.notification!.title! == 'Trip Monitoring'.tr) {
|
||
if (Platform.isAndroid) {
|
||
notificationController.showNotification(
|
||
'Trip Monitoring'.tr, '', 'iphone_ringtone');
|
||
}
|
||
var myListString = message.data['DriverList'];
|
||
var myList = jsonDecode(myListString) as List<dynamic>;
|
||
Get.toNamed('/tripmonitor', arguments: {
|
||
'rideId': myList[0].toString(),
|
||
'driverId': myList[1].toString(),
|
||
});
|
||
} else if (message.notification!.title! == 'token change'.tr) {
|
||
if (Platform.isAndroid) {
|
||
notificationController.showNotification(
|
||
'token change'.tr, 'token change'.tr, 'cancel');
|
||
}
|
||
GoogleSignInHelper.signOut();
|
||
} else if (message.notification!.title! ==
|
||
'Driver Is Going To Passenger'.tr) {
|
||
Get.find<MapPassengerController>().isDriverInPassengerWay = true;
|
||
Get.find<MapPassengerController>().update();
|
||
if (Platform.isAndroid) {
|
||
notificationController.showNotification('Driver is Going To You'.tr,
|
||
'Please stay on the picked point.'.tr, 'tone1');
|
||
}
|
||
// Get.snackbar('Driver is Going To Passenger', '',
|
||
// backgroundColor: AppColor.greenColor);
|
||
} else if (message.notification!.title! == 'message From passenger') {
|
||
if (Platform.isAndroid) {
|
||
notificationController.showNotification(
|
||
'message From passenger'.tr, ''.tr, 'ding');
|
||
}
|
||
passengerDialog(message.notification!.body!);
|
||
|
||
update();
|
||
} else if (message.notification!.title! == 'message From Driver') {
|
||
if (Platform.isAndroid) {
|
||
notificationController.showNotification(
|
||
'message From Driver'.tr, ''.tr, 'ding');
|
||
}
|
||
passengerDialog(message.notification!.body!);
|
||
|
||
update();
|
||
} else if (message.notification!.title! == 'Trip is Begin'.tr) {
|
||
if (Platform.isAndroid) {
|
||
notificationController.showNotification(
|
||
'Trip is Begin'.tr, ''.tr, 'start');
|
||
}
|
||
Get.find<MapPassengerController>().getBeginRideFromDriver();
|
||
// Get.snackbar('RideIsBegin', '', backgroundColor: AppColor.greenColor);
|
||
box.write(BoxName.passengerWalletTotal, '0');
|
||
update();
|
||
} else if (message.notification!.title! == 'Hi ,I will go now'.tr) {
|
||
// Get.snackbar('Hi ,I will go now', '',
|
||
// backgroundColor: AppColor.greenColor);
|
||
if (Platform.isAndroid) {
|
||
notificationController.showNotification(
|
||
'Passenger come to you'.tr, 'Hi ,I will go now'.tr, 'ding');
|
||
}
|
||
update();
|
||
} else if (message.notification!.title! == 'Hi ,I Arrive your site'.tr) {
|
||
if (Platform.isAndroid) {
|
||
notificationController.showNotification(
|
||
'Hi ,I Arrive your site'.tr, ''.tr, 'ding');
|
||
}
|
||
driverArrivePassengerDialoge();
|
||
|
||
update();
|
||
} else if (message.notification!.title! == "Cancel Trip from driver") {
|
||
Get.back();
|
||
if (Platform.isAndroid) {
|
||
notificationController.showNotification("Cancel Trip from driver".tr,
|
||
"We will look for a new driver.\nPlease wait.".tr, 'cancel');
|
||
}
|
||
Get.defaultDialog(
|
||
title: "The driver canceled your ride.".tr,
|
||
middleText: "We will look for a new driver.\nPlease wait.".tr,
|
||
confirm: MyElevatedButton(
|
||
kolor: AppColor.greenColor,
|
||
title: 'Ok'.tr,
|
||
onPressed: () async {
|
||
Get.back();
|
||
await Get.find<MapPassengerController>()
|
||
.reSearchAfterCanceledFromDriver();
|
||
},
|
||
),
|
||
cancel: MyElevatedButton(
|
||
title: 'Cancel'.tr,
|
||
kolor: AppColor.redColor,
|
||
onPressed: () {
|
||
Get.offAll(() => const MapPagePassenger());
|
||
},
|
||
)
|
||
// Get.find<MapPassengerController>()
|
||
// .searchNewDriverAfterRejectingFromDriver();
|
||
);
|
||
} else if (message.notification!.title! == 'Driver Finish Trip'.tr) {
|
||
var myListString = message.data['DriverList'];
|
||
Log.print('myListString: ${myListString}');
|
||
var driverList = jsonDecode(myListString) as List<dynamic>;
|
||
Log.print('driverList: ${driverList}');
|
||
if (Platform.isAndroid) {
|
||
notificationController.showNotification(
|
||
"Driver Finish Trip".tr,
|
||
'you will pay to Driver'.tr + ' ${driverList[3].toString()} \$'.tr,
|
||
'tone1');
|
||
}
|
||
Get.find<AudioRecorderController>().stopRecording();
|
||
if (double.parse(box.read(BoxName.passengerWalletTotal)) < 0) {
|
||
box.write(BoxName.passengerWalletTotal, 0);
|
||
}
|
||
print(333);
|
||
Get.find<MapPassengerController>().tripFinishedFromDriver();
|
||
NotificationController().showNotification(
|
||
'Don’t forget your personal belongings.'.tr,
|
||
'Please make sure you have all your personal belongings and that any remaining fare, if applicable, has been added to your wallet before leaving. Thank you for choosing the Intaleq app'
|
||
.tr,
|
||
'ding');
|
||
print(267);
|
||
Get.to(() => RateDriverFromPassenger(), arguments: {
|
||
'driverId': driverList[0].toString(),
|
||
'rideId': driverList[1].toString(),
|
||
'price': driverList[3].toString()
|
||
});
|
||
} else if (message.notification!.title! == "Finish Monitor".tr) {
|
||
Get.defaultDialog(
|
||
titleStyle: AppStyle.title,
|
||
title: 'Trip finished '.tr,
|
||
middleText: '',
|
||
confirm: MyElevatedButton(
|
||
title: 'Ok'.tr,
|
||
onPressed: () {
|
||
Get.offAll(() => const MapPagePassenger());
|
||
}));
|
||
}
|
||
// else if (message.notification!.title! == "Trip Monitoring".tr) {
|
||
// Get.to(() => const TripMonitor());
|
||
// }
|
||
else if (message.notification!.title! == 'Call Income') {
|
||
try {
|
||
var myListString = message.data['DriverList'];
|
||
var driverList = jsonDecode(myListString) as List<dynamic>;
|
||
// if (Platform.isAndroid) {
|
||
if (Platform.isAndroid) {
|
||
notificationController.showNotification(
|
||
'Call Income'.tr,
|
||
message.notification!.body!,
|
||
'iphone_ringtone',
|
||
);
|
||
}
|
||
// }
|
||
// Assuming GetMaterialApp is initialized and context is valid for navigation
|
||
// Get.to(() => PassengerCallPage(
|
||
// channelName: driverList[1].toString(),
|
||
// token: driverList[0].toString(),
|
||
// remoteID: driverList[2].toString(),
|
||
// ));
|
||
} catch (e) {}
|
||
} else if (message.notification!.title! == 'Call Income from Driver'.tr) {
|
||
try {
|
||
var myListString = message.data['DriverList'];
|
||
var driverList = jsonDecode(myListString) as List<dynamic>;
|
||
// if (Platform.isAndroid) {
|
||
if (Platform.isAndroid) {
|
||
notificationController.showNotification(
|
||
'Call Income'.tr,
|
||
message.notification!.body!,
|
||
'iphone_ringtone',
|
||
);
|
||
}
|
||
// Assuming GetMaterialApp is initialized and context is valid for navigation
|
||
// Get.to(() => PassengerCallPage(
|
||
// channelName: driverList[1].toString(),
|
||
// token: driverList[0].toString(),
|
||
// remoteID: driverList[2].toString(),
|
||
// ));
|
||
} catch (e) {}
|
||
} else if (message.notification!.title! == 'Call End'.tr) {
|
||
try {
|
||
var myListString = message.data['DriverList'];
|
||
var driverList = jsonDecode(myListString) as List<dynamic>;
|
||
if (Platform.isAndroid) {
|
||
notificationController.showNotification(
|
||
'Call End'.tr,
|
||
message.notification!.body!,
|
||
'ding',
|
||
);
|
||
}
|
||
// Assuming GetMaterialApp is initialized and context is valid for navigation
|
||
// Get.off(const CallPage());
|
||
} catch (e) {}
|
||
} else if (message.notification!.title! == 'Driver Cancelled Your Trip') {
|
||
// Get.snackbar(
|
||
// 'You will be pay the cost to driver or we will get it from you on next trip'
|
||
// .tr,
|
||
// 'message',
|
||
// backgroundColor: AppColor.redColor);
|
||
if (Platform.isAndroid) {
|
||
notificationController.showNotification(
|
||
'Driver Cancelled Your Trip'.tr,
|
||
'you will pay to Driver you will be pay the cost of driver time look to your Intaleq Wallet'
|
||
.tr,
|
||
'cancel');
|
||
}
|
||
box.write(BoxName.parentTripSelected, false);
|
||
box.remove(BoxName.tokenParent);
|
||
|
||
Get.find<MapPassengerController>().restCounter();
|
||
Get.offAll(() => const MapPagePassenger());
|
||
}
|
||
// else if (message.notification!.title! == 'Order Applied') {
|
||
// Get.snackbar(
|
||
// "The order has been accepted by another driver."
|
||
// .tr, // Corrected grammar
|
||
// "Be more mindful next time to avoid dropping orders."
|
||
// .tr, // Improved sentence structure
|
||
// backgroundColor: AppColor.yellowColor,
|
||
// snackPosition: SnackPosition.BOTTOM,
|
||
// );
|
||
// }
|
||
|
||
else if (message.notification!.title! == 'Order Applied'.tr) {
|
||
if (Platform.isAndroid) {
|
||
notificationController.showNotification(
|
||
'The order Accepted by another Driver'.tr,
|
||
'We regret to inform you that another driver has accepted this order.'
|
||
.tr,
|
||
'order');
|
||
}
|
||
}
|
||
}
|
||
|
||
SnackbarController driverAppliedTripSnakBar() {
|
||
return Get.snackbar(
|
||
'Driver Applied the Ride for You'.tr,
|
||
'',
|
||
colorText: AppColor.greenColor,
|
||
duration: const Duration(seconds: 3),
|
||
snackPosition: SnackPosition.TOP,
|
||
titleText: Text(
|
||
'Applied'.tr,
|
||
style: const TextStyle(color: AppColor.redColor),
|
||
),
|
||
messageText: Text(
|
||
'Driver Applied the Ride for You'.tr,
|
||
style: AppStyle.title,
|
||
),
|
||
icon: const Icon(Icons.approval),
|
||
shouldIconPulse: true,
|
||
margin: const EdgeInsets.all(16),
|
||
padding: const EdgeInsets.all(16),
|
||
);
|
||
}
|
||
|
||
Future<dynamic> driverArrivePassengerDialoge() {
|
||
return Get.defaultDialog(
|
||
barrierDismissible: false,
|
||
title: 'Hi ,I Arrive your site'.tr,
|
||
titleStyle: AppStyle.title,
|
||
middleText: 'Please go to Car Driver'.tr,
|
||
middleTextStyle: AppStyle.title,
|
||
confirm: MyElevatedButton(
|
||
title: 'Ok I will go now.'.tr,
|
||
onPressed: () {
|
||
sendNotificationToPassengerToken(
|
||
'Hi ,I will go now',
|
||
'I will go now'.tr,
|
||
Get.find<MapPassengerController>().driverToken,
|
||
[],
|
||
'ding.wav');
|
||
Get.find<MapPassengerController>()
|
||
.startTimerDriverWaitPassenger5Minute();
|
||
|
||
Get.back();
|
||
Get.find<MapPassengerController>().remainingTime = 0;
|
||
Get.find<MapPassengerController>().update();
|
||
}));
|
||
}
|
||
|
||
Future<dynamic> passengerDialog(String message) {
|
||
return Get.defaultDialog(
|
||
barrierDismissible: false,
|
||
title: 'message From Driver'.tr,
|
||
titleStyle: AppStyle.title,
|
||
middleTextStyle: AppStyle.title,
|
||
middleText: message.tr,
|
||
confirm: MyElevatedButton(
|
||
title: 'Ok'.tr,
|
||
onPressed: () {
|
||
// Get.find<FirebaseMessagesController>().sendNotificationToPassengerToken(
|
||
// 'Hi ,I will go now'.tr,
|
||
// 'I will go now'.tr,
|
||
// Get.find<MapPassengerController>().driverToken, []);
|
||
// Get.find<MapPassengerController>()
|
||
// .startTimerDriverWaitPassenger5Minute();
|
||
|
||
Get.back();
|
||
}));
|
||
}
|
||
|
||
Future<dynamic> driverFinishTripDialoge(List<dynamic> driverList) {
|
||
return Get.defaultDialog(
|
||
title: 'Driver Finish Trip'.tr,
|
||
content: const DriverTipWidget(),
|
||
confirm: MyElevatedButton(
|
||
title: 'Yes'.tr,
|
||
onPressed: () async {
|
||
Get.to(() => RateDriverFromPassenger(), arguments: {
|
||
'driverId': driverList[0].toString(),
|
||
'rideId': driverList[1].toString(),
|
||
'price': driverList[3].toString()
|
||
});
|
||
},
|
||
kolor: AppColor.greenColor,
|
||
),
|
||
cancel: MyElevatedButton(
|
||
title: 'No,I want'.tr,
|
||
onPressed: () {
|
||
Get.to(() => RateDriverFromPassenger(), arguments: {
|
||
'driverId': driverList[0].toString(),
|
||
'rideId': driverList[1].toString(),
|
||
'price': driverList[3].toString()
|
||
});
|
||
},
|
||
kolor: AppColor.redColor,
|
||
));
|
||
}
|
||
|
||
void sendNotificationAll(String title, body, tone) async {
|
||
// Get the token you want to subtract.
|
||
String token = box.read(BoxName.tokenFCM);
|
||
tokens = box.read(BoxName.tokens);
|
||
// Subtract the token from the list of tokens.
|
||
tokens.remove(token);
|
||
|
||
// Save the list of tokens back to the box.
|
||
// box.write(BoxName.tokens, tokens);
|
||
tokens = box.read(BoxName.tokens);
|
||
for (var i = 0; i < tokens.length; i++) {
|
||
http
|
||
.post(
|
||
Uri.parse('https://fcm.googleapis.com/fcm/send'),
|
||
headers: <String, String>{
|
||
'Content-Type': 'application/json',
|
||
'Authorization': 'key=${AK.serverAPI}'
|
||
},
|
||
body: jsonEncode({
|
||
'message': {
|
||
'token': token,
|
||
'notification': {
|
||
'title': title,
|
||
'body': body,
|
||
},
|
||
// 'data': {
|
||
// 'DriverList': jsonEncode(data),
|
||
// },
|
||
'android': {
|
||
'priority': 'HIGH ', // Set priority to high
|
||
'notification': {
|
||
'sound': tone,
|
||
},
|
||
},
|
||
'apns': {
|
||
'headers': {
|
||
'apns-priority': '10', // Set APNs priority to 10
|
||
},
|
||
'payload': {
|
||
'aps': {
|
||
'sound': tone,
|
||
},
|
||
},
|
||
},
|
||
},
|
||
}),
|
||
)
|
||
.whenComplete(() {})
|
||
.catchError((e) {});
|
||
}
|
||
}
|
||
|
||
// for (var i = 0; i < tokens.length; i++) {
|
||
// http
|
||
// .post(Uri.parse('https://fcm.googleapis.com/fcm/send'),
|
||
// headers: <String, String>{
|
||
// 'Content-Type': 'application/json',
|
||
// 'Authorization': 'key=${storage.read(key: BoxName.serverAPI}'
|
||
// },
|
||
// body: jsonEncode({
|
||
// 'notification': <String, dynamic>{
|
||
// 'title': title,
|
||
// 'body': body,
|
||
// 'sound': 'true'
|
||
// },
|
||
// 'priority': 'HIGH ',
|
||
// 'data': <String, dynamic>{
|
||
// 'click_action': 'FLUTTER_NOTIFICATION_CLICK',
|
||
// 'id': '1',
|
||
// 'status': 'done'
|
||
// },
|
||
// 'to': tokens[i],
|
||
// }))
|
||
// .whenComplete(() {})
|
||
// .catchError((e) {
|
||
// });
|
||
// }
|
||
// }
|
||
|
||
late String serviceAccountKeyJson;
|
||
// '{"type": "service_account", "project_id": "intaleq-d48a7", "private_key_id": "d63a627dad96d0050c08a76c2920b1e48ddc4d38", "private_key": "-----BEGIN PRIVATE KEY-----\\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDHgHWUIlGskFWT\\nkjBvSiAYzXz51NbyMtqlvq1rZaiokd/yzqcEsjgxcAEGap93gRu72cuJ7QzDOpec\\nXSmhQwaGrdDyGyuS5x8nBa9ea3QEUGKjk975OhgIDoaIX2YHjah+jf/p3CPvwovC\\n+qypLsErv5DtcFfKtHkL+Z8gKJojU3p0gP2cVLHlhodGG4767w1f70fIv5LmQRHh\\nE0x5GgjO7MfA1CJewgHDWzj9GTuTd9o3G5nF6ojn8H1EOWminNDrsHAagsplY7iV\\nNmdvGoIAg2kRt66y5k4Li7EiH3e2ILvomGvUe3ahxBTcyFAt7UuAC5aPTmB0OCtN\\n39vMkJGtAgMBAAECggEAQ/FoWcBMX4AyXNUzQJuWjcvhzbXiVE7kbwEez44qH+q6\\nQdeGQw+tGo0iFDzYvVrPhqzYaEs+hvib7Kk/xcdtYA2vNNzy/I9Q6TnC7V2b/+Ie\\njcYM8IUL7SaBQ811kon4gc07hDowVPXFImy7w8yEBjGyGmMhywumk+D6A/o/8Fph\\n3lGRzgYZ7K7+mXxDpJVFp8DwX+uqP/3wOzcITXE12GZpvB+re7TQTs01qjsSTJ3/\\nCZMC6CvwYr3BvJzvgrn2TNZ6N6yowHE2iJo/HnoY/DutiB1V0B2EAMgcy05ZUouH\\nnTTOMAyV5LdcxgCtzlz+meCuhV5SUtfSz27bnUluMwKBgQDz+qJM38NhUpW7tmxZ\\nQsYwlo3Zp2a38UV8VC4mNDM9jjsft9QRHShos7potlIvmn9ryxP87SGNZrW9xy/k\\ngvTbDXu65/TwCUa3HYFCC+eJ5S4bBK/ctFwn1sr5AFjxavY2VV6YHUIzGezo8Bsj\\n1R5IGy3UHreTWngDapJYpA3JQwKBgQDRVNK7UP/Qt4qovrTVlNJ5mHjpwk7VoKBC\\nV0yrfbYVjYETFRFMrsKkcwCTQ3uk3lEl/UzAt2vV6o4Ql8KDzYJ/8ZHHXp9Z2eK9\\nTgR2fOIaEh2JJUjyVAUtuJo7RFl61K3a080+ZGWuZCY6K+prGneFqGuJ7XTtveGy\\njIsZTUhSTwKBgQCS0n5/Qp1iYP+IsjQr1zpLnR6KH+p5wXEua75F8V3wqjo8UTUG\\ng4SA1b/VKfr1eMU7ij9iExYA8RFnvom8u248sLWH+fT1yq9KnS/fHijdXBTN35kx\\neTyIIQOOqz3bMqIuelttsRXYiL6AQ5Yhjywk+m4u27lfrK7SZ3zgaQF+3wKBgEBy\\nfgKfmHLY3z6+oAwVqos3LxrA8OaCcnSaTgeKR5HxI+kNFmtmbpSUt3ufTiTfMVqh\\n1oyKrA+LDDv9jSxpDCF57SjVb/gIxe8EYwlbv3zJUQCVUxUQWxvNduaCT44qhnAV\\nv13TKR78xGwqcxyQZHXo+VrYmaRMTn1bGcQrb/WvAoGAIWUnnGQsvf6SwPQ/7gXC\\nVAq4i3E+coLStVyPK552HVorKa7J+TQnNBGHjCaQhxfCgp59/4qeT5AizzQaMhuS\\noGiUwGeo4RY4A1EEGoUpUk3zWZfC+bAjHVDyIjfN0YfxobL6Sh/97N68PMzb6ppq\\nybvddSGGsqZgucSxkEhIdTw=\\n-----END PRIVATE KEY-----\\n", "client_email": "firebase-adminsdk-fbsvc@intaleq-d48a7.iam.gserviceaccount.com", "client_id": "100558924056484926665", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-fbsvc%40intaleq-d48a7.iam.gserviceaccount.com", "universe_domain": "googleapis.com"}';
|
||
@override
|
||
Future<void> onInit() async {
|
||
super.onInit();
|
||
try {
|
||
var encryptedKey = Env.privateKeyFCM;
|
||
// Log.print('encryptedKey: ${encryptedKey}');
|
||
serviceAccountKeyJson =
|
||
EncryptionHelper.instance.decryptData(encryptedKey);
|
||
// Log.print('serviceAccountKeyJson: ${serviceAccountKeyJson}');
|
||
} catch (e) {
|
||
print('🔴 Error decrypting FCM key: $e');
|
||
}
|
||
}
|
||
|
||
Future<void> sendNotificationToDriverMAP(
|
||
String title, String body, String token, List<String> data, String tone,
|
||
{int retryCount = 1}) async {
|
||
try {
|
||
if (serviceAccountKeyJson.isEmpty) {
|
||
print("🔴 Error: Service Account Key is empty");
|
||
return;
|
||
}
|
||
|
||
// Initialize AccessTokenManager
|
||
final accessTokenManager = AccessTokenManager(serviceAccountKeyJson);
|
||
// Log.print(
|
||
// 'accessTokenManager: ${accessTokenManager.serviceAccountJsonKey}');
|
||
|
||
// Obtain an OAuth 2.0 access token
|
||
final accessToken = await accessTokenManager.getAccessToken();
|
||
// Log.print('accessToken: ${accessToken}');
|
||
|
||
// Send the notification
|
||
final response = await http.post(
|
||
Uri.parse(
|
||
'https://fcm.googleapis.com/v1/projects/intaleq-d48a7/messages:send'),
|
||
headers: <String, String>{
|
||
'Content-Type': 'application/json',
|
||
'Authorization': 'Bearer $accessToken',
|
||
},
|
||
body: jsonEncode({
|
||
'message': {
|
||
'token': token,
|
||
'notification': {
|
||
'title': title,
|
||
'body': body,
|
||
},
|
||
'data': {
|
||
'DriverList': jsonEncode(data),
|
||
},
|
||
'android': {
|
||
'priority': 'HIGH ', // Set priority to high
|
||
'notification': {
|
||
'sound': tone,
|
||
},
|
||
},
|
||
'apns': {
|
||
'headers': {
|
||
'apns-priority': '10', // Set APNs priority to 10
|
||
},
|
||
'payload': {
|
||
'aps': {
|
||
'sound': tone,
|
||
},
|
||
},
|
||
},
|
||
},
|
||
}),
|
||
);
|
||
|
||
if (response.statusCode == 200) {
|
||
print(
|
||
'Notification sent successfully. Status code: ${response.statusCode}');
|
||
// print('Response token: ${token}');
|
||
} else {
|
||
print(
|
||
'Failed to send notification. Status code: ${response.statusCode}');
|
||
print('Response body: ${response.body}');
|
||
if (retryCount > 0) {
|
||
print('Retrying... Attempts remaining: $retryCount');
|
||
await Future.delayed(
|
||
Duration(seconds: 2)); // Optional delay before retrying
|
||
return sendNotificationToDriverMAP(title, body, token, data, tone,
|
||
retryCount: retryCount - 1);
|
||
}
|
||
}
|
||
} catch (e) {
|
||
print('Error sending notification: $e');
|
||
if (retryCount > 0) {
|
||
print('Retrying... Attempts remaining: $retryCount');
|
||
await Future.delayed(
|
||
Duration(seconds: 2)); // Optional delay before retrying
|
||
return sendNotificationToDriverMAP(title, body, token, data, tone,
|
||
retryCount: retryCount - 1);
|
||
}
|
||
}
|
||
}
|
||
|
||
void sendNotificationToPassengerToken(
|
||
String title, body, token, List<String> map, String tone) async {
|
||
try {
|
||
if (serviceAccountKeyJson.isEmpty) {
|
||
print("🔴 Error: Service Account Key is empty");
|
||
return;
|
||
}
|
||
// Initialize AccessTokenManager
|
||
final accessTokenManager = AccessTokenManager(serviceAccountKeyJson);
|
||
|
||
// Obtain an OAuth 2.0 access token
|
||
final accessToken = await accessTokenManager.getAccessToken();
|
||
// Log.print('accessToken: ${accessToken}');
|
||
|
||
// Send the notification
|
||
final response = await http.post(
|
||
Uri.parse(
|
||
'https://fcm.googleapis.com/v1/projects/intaleq-d48a7/messages:send'),
|
||
headers: <String, String>{
|
||
'Content-Type': 'application/json',
|
||
'Authorization': 'Bearer $accessToken',
|
||
},
|
||
body: jsonEncode({
|
||
'message': {
|
||
'token': token,
|
||
'notification': {
|
||
'title': title,
|
||
'body': body,
|
||
},
|
||
'android': {
|
||
'priority': 'HIGH ', // Set priority to high
|
||
'notification': {
|
||
'sound': tone,
|
||
},
|
||
},
|
||
'apns': {
|
||
'headers': {
|
||
'apns-priority': '10', // Set APNs priority to 10
|
||
},
|
||
'payload': {
|
||
'aps': {
|
||
'sound': tone,
|
||
},
|
||
},
|
||
},
|
||
},
|
||
}),
|
||
);
|
||
|
||
if (response.statusCode == 200) {
|
||
print('✅ Notification sent successfully!');
|
||
} else {
|
||
print(
|
||
'🔴 Failed to send notification. Status code: ${response.statusCode}');
|
||
print('Response body: ${response.body}');
|
||
}
|
||
} catch (e) {
|
||
print('🔴 Error sending notification: $e');
|
||
}
|
||
}
|
||
}
|
||
|
||
class DriverTipWidget extends StatelessWidget {
|
||
const DriverTipWidget({
|
||
super.key,
|
||
});
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return GetBuilder<MapPassengerController>(builder: (controller) {
|
||
return Column(
|
||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||
children: [
|
||
// Text(
|
||
// '${'Your fee is '.tr}${Get.find<MapPassengerController>().totalPassenger.toStringAsFixed(2)}'),
|
||
Text(
|
||
'Do you want to pay Tips for this Driver'.tr,
|
||
textAlign: TextAlign.center,
|
||
),
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||
children: [
|
||
InkWell(
|
||
onTap: () {
|
||
box.write(BoxName.tipPercentage, '0.05');
|
||
|
||
Toast.show(
|
||
context,
|
||
'${'Tip is '.tr}${(controller.totalPassenger) * (double.parse(box.read(BoxName.tipPercentage.toString())))}',
|
||
AppColor.blueColor);
|
||
controller.update();
|
||
},
|
||
child: Container(
|
||
decoration: BoxDecoration(border: Border.all()),
|
||
child: const Padding(
|
||
padding: EdgeInsets.all(4),
|
||
child: Center(
|
||
child: Text('5%'),
|
||
),
|
||
),
|
||
),
|
||
),
|
||
InkWell(
|
||
onTap: () {
|
||
box.write(BoxName.tipPercentage, '0.10');
|
||
Toast.show(
|
||
context,
|
||
'${'Tip is'.tr} ${(controller.totalPassenger) * (double.parse(box.read(BoxName.tipPercentage.toString())))}',
|
||
AppColor.blueColor);
|
||
controller.update();
|
||
},
|
||
child: Container(
|
||
decoration: BoxDecoration(border: Border.all()),
|
||
child: const Center(
|
||
child: Padding(
|
||
padding: EdgeInsets.all(5),
|
||
child: Text('10%'),
|
||
),
|
||
),
|
||
),
|
||
),
|
||
InkWell(
|
||
onTap: () {
|
||
box.write(BoxName.tipPercentage, '0.15');
|
||
Toast.show(
|
||
context,
|
||
'${'Tip is'.tr} ${(controller.totalPassenger) * (double.parse(box.read(BoxName.tipPercentage.toString())))}',
|
||
AppColor.blueColor);
|
||
controller.update();
|
||
},
|
||
child: Container(
|
||
decoration: BoxDecoration(border: Border.all()),
|
||
child: const Center(
|
||
child: Padding(
|
||
padding: EdgeInsets.all(5),
|
||
child: Text('15%'),
|
||
),
|
||
),
|
||
),
|
||
),
|
||
InkWell(
|
||
onTap: () {
|
||
box.write(BoxName.tipPercentage, '0.20');
|
||
Toast.show(
|
||
context,
|
||
'${'Tip is'.tr} ${(controller.totalPassenger) * (double.parse(box.read(BoxName.tipPercentage.toString())))}',
|
||
AppColor.blueColor);
|
||
controller.update();
|
||
},
|
||
child: Container(
|
||
decoration: BoxDecoration(border: Border.all()),
|
||
child: const Center(
|
||
child: Padding(
|
||
padding: EdgeInsets.all(5),
|
||
child: Text('20%'),
|
||
),
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||
children: [
|
||
MyElevatedButton(
|
||
kolor: AppColor.redColor,
|
||
title: 'No i want'.tr,
|
||
onPressed: () {
|
||
box.write(BoxName.tipPercentage, '0');
|
||
controller.update();
|
||
}),
|
||
Container(
|
||
decoration: AppStyle.boxDecoration1,
|
||
child: Padding(
|
||
padding: const EdgeInsets.all(6),
|
||
child: Text(
|
||
'${(controller.totalPassenger) * (double.parse(box.read(BoxName.tipPercentage.toString())))} ${box.read(BoxName.countryCode) == 'Egypt' ? 'LE'.tr : 'JOD'.tr}',
|
||
style: AppStyle.title,
|
||
),
|
||
),
|
||
),
|
||
],
|
||
)
|
||
],
|
||
);
|
||
});
|
||
}
|
||
}
|