25-10-11/1

This commit is contained in:
Hamza-Ayed
2025-11-06 12:29:17 +03:00
parent 14484fcd8f
commit a69e4c6912
46 changed files with 14145 additions and 13529 deletions

View File

@@ -1,32 +1,25 @@
import 'dart:convert';
import 'dart:io';
import 'package:sefer_driver/constant/api_key.dart';
import 'package:sefer_driver/controller/home/captin/home_captain_controller.dart';
import 'package:sefer_driver/views/widgets/error_snakbar.dart';
import 'package:sefer_driver/views/widgets/mydialoug.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:sefer_driver/views/widgets/elevated_btn.dart';
import '../../constant/box_name.dart';
import '../../constant/colors.dart';
import '../../constant/style.dart';
import '../../env/env.dart';
import '../../main.dart';
import '../../print.dart';
import '../../views/auth/captin/criminal_documents_page.dart';
import '../../views/home/Captin/home_captain/home_captin.dart';
import '../../views/home/Captin/orderCaptin/order_speed_request.dart';
import '../../views/home/Captin/orderCaptin/order_request_page.dart';
import '../../views/home/Captin/orderCaptin/vip_order_page.dart';
import '../auth/google_sign.dart';
import '../functions/encrypt_decrypt.dart';
import '../functions/face_detect.dart';
import 'access_token.dart';
import 'local_notification.dart';
import 'notification_service.dart';
class FirebaseMessagesController extends GetxController {
final fcmToken = FirebaseMessaging.instance;
@@ -76,6 +69,9 @@ class FirebaseMessagesController extends GetxController {
Log.print('token fcm driver: ${token}');
box.write(BoxName.tokenDriver, (token!));
});
// 🔹 الاشتراك في topic
await fcmToken.subscribeToTopic("drivers"); // أو "users" حسب نوع المستخدم
print("Subscribed to 'drivers' topic ✅");
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
// If the app is in the background or terminated, show a system tray message
@@ -100,225 +96,135 @@ class FirebaseMessagesController extends GetxController {
}
Future<void> fireBaseTitles(RemoteMessage message) async {
if (message.notification!.title! == 'Order') {
if (Platform.isAndroid) {
notificationController.showNotification(
message.notification!.title.toString(),
message.notification!.body.toString(),
'tone1',
'');
}
// await FirebaseMessagesController().showOverlayNotification(message);
var myListString = message.data['DriverList'];
// var points = message.data['PolylineJson'];
// [!! تعديل جوهري !!]
// اقرأ "النوع" من حمولة البيانات، وليس من العنوان
String category = message.data['category'] ?? '';
var myList = jsonDecode(myListString) as List<dynamic>;
// var myPoints = jsonDecode(points) as List<dynamic>;
driverToken = myList[14].toString();
// This is for location using and uploading status
Get.put(HomeCaptainController()).changeRideId();
update();
Get.to(() => OrderRequestPage(), arguments: {
// Get.to(() => OrderRequestPage(), arguments: {
'myListString': myListString,
'DriverList': myList,
// 'PolylineJson': myPoints,
'body': message.notification!.body
});
} else if (message.notification!.title == 'OrderVIP') {
var myListString = message.data['DriverList'];
// اقرأ العنوان والنص (للعرض)
String title = message.notification?.title ?? '';
String body = message.notification?.body ?? '';
var myList = jsonDecode(myListString) as List<dynamic>;
// driverToken = myList[10].toString();
if (Platform.isAndroid) {
notificationController.showNotification(
'OrderVIP'.tr, 'OrderVIP'.tr, 'order', '');
}
Get.to(VipOrderPage(), arguments: {
'myListString': myListString,
'DriverList': myList,
// 'PolylineJson': myPoints,
'body': message.notification!.body
});
} else if (message.notification!.title == 'Cancel Trip'.tr) {
if (Platform.isAndroid) {
notificationController.showNotification(
'Cancel Trip'.tr, 'Passenger Cancel Trip'.tr, 'cancel', '');
}
cancelTripDialog();
} else if (message.notification!.title == 'VIP Order') {
var myListString = message.data['DriverList'];
var driverList = jsonDecode(myListString) as List<dynamic>;
if (Platform.isAndroid) {
notificationController.showNotification(
'VIP Order'.tr, '', 'order', '');
}
MyDialog().getDialog('VIP Order'.tr, 'midTitle', () {
// sendNotificationToPassengerToken(
// 'VIP Order Accepted'.tr,
// 'The driver accepted your trip'.tr,
// driverList[0],
// [driverList[1]],
// 'order');
NotificationService.sendNotification(
target: driverList[0].toString(),
title: 'VIP Order Accepted'.tr,
body: 'The driver accepted your trip'.tr,
isTopic: false, // Important: this is a token
tone: 'order',
driverList: [],
);
});
// Get.to(const VipOrderPage());
} else if (message.notification!.title == 'message From passenger') {
if (Platform.isAndroid) {
notificationController.showNotification(
'message From passenger'.tr, ''.tr, 'ding', '');
}
MyDialog().getDialog(
'message From passenger'.tr, message.notification!.body!, () {
Get.back();
});
} else if (message.notification!.title == 'Cancel') {
if (Platform.isAndroid) {
notificationController.showNotification(
'Cancel'.tr, ''.tr, 'cancel', '');
}
MyDialog().getDialog(
'Passenger Cancel Trip'.tr,
'Trip Cancelled. The cost of the trip will be added to your wallet.'
.tr, () {
box.write(BoxName.rideStatus, 'Cancel');
Log.print('rideStatus from 184 : ${box.read(BoxName.rideStatus)}');
Get.offAll(HomeCaptain());
});
// cancelTripDialog1();
} else if (message.notification!.title! == 'token change') {
// notificationController
// .showNotification('token change'.tr, 'token change', 'cancel');
// GoogleSignInHelper.signOut();
GoogleSignInHelper.signOut();
} else if (message.notification!.title! == 'face detect') {
if (Platform.isAndroid) {
notificationController.showNotification(
'face detect'.tr, ''.tr, 'tone2', '');
}
String result0 = await faceDetector();
// Handle the result here, e.g., show a dialog or update the UI
var result = jsonDecode(result0);
MyDialogContent().getDialog(
'Face Detection Result'.tr,
Text(
result['similar'].toString() == 'true'
? 'similar'.tr
: 'not similar'.tr,
style: AppStyle.title,
),
() {
Get.back();
},
);
update();
} else if (message.notification!.title! == 'Hi ,I will go now') {
if (Platform.isAndroid) {
notificationController.showNotification(
'Passenger come to you'.tr, 'Hi ,I will go now'.tr, 'tone2', '');
}
update();
} else if (message.notification!.title! == 'Call Income'.tr) {
try {
var myListString = message.data['passengerList'];
var driverList = jsonDecode(myListString) as List<dynamic>;
// if (Platform.isAndroid) {
// استخدم switch لسهولة القراءة والصيانة
switch (category) {
case 'ORDER':
case 'Order': // Handle both cases for backward compatibility
if (Platform.isAndroid) {
notificationController.showNotification('Call Income'.tr,
message.notification!.body!, 'iphone_ringtone', '');
notificationController.showNotification(title, body, 'tone1', '');
}
// }
// 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 Passenger'.tr) {
try {
var myListString = message.data['passengerList'];
var driverList = jsonDecode(myListString) as List<dynamic>;
// if (Platform.isAndroid) {
if (Platform.isAndroid) {
notificationController.showNotification('Call Income'.tr,
message.notification!.body!, 'iphone_ringtone', '');
var myListString = message.data['DriverList'];
if (myListString != null) {
var myList = jsonDecode(myListString) as List<dynamic>;
driverToken = myList[14].toString();
Get.put(HomeCaptainController()).changeRideId();
update();
Get.to(() => OrderRequestPage(), arguments: {
'myListString': myListString,
'DriverList': myList,
'body': body
});
}
// }
// Assuming GetMaterialApp is initialized and context is valid for navigation
// Get.to(() => CallPage(
// // channelName: driverList[1].toString(),
// // token: driverList[0].toString(),
// // remoteID: driverList[2].toString(),
// ));
} catch (e) {}
} else if (message.notification!.title! ==
"Criminal Document Required".tr) {
if (Platform.isAndroid) {
notificationController.showNotification("Criminal Document Required".tr,
message.notification!.body!, 'tone2', '');
}
MyDialog().getDialog(
"Criminal Document Required".tr, 'You should have upload it .'.tr,
() {
Get.to(() => const CriminalDocumemtPage());
});
Get.to(() => const CriminalDocumemtPage());
} else if (message.notification!.title! == 'Call End'.tr) {
try {
var myListString = message.data['passengerList'];
var driverList = jsonDecode(myListString) as List<dynamic>;
break;
case 'OrderVIP':
var myListString = message.data['DriverList'];
if (myListString != null) {
var myList = jsonDecode(myListString) as List<dynamic>;
if (Platform.isAndroid) {
notificationController.showNotification(title, body, 'order', '');
}
Get.to(VipOrderPage(), arguments: {
'myListString': myListString,
'DriverList': myList,
'body': body
});
}
break;
case 'Cancel Trip':
case 'TRIP_CANCELLED':
if (Platform.isAndroid) {
notificationController.showNotification(
'Call End'.tr, message.notification!.body!, 'tone2', '');
title, 'Passenger Cancel Trip'.tr, 'cancel', '');
}
// Assuming GetMaterialApp is initialized and context is valid for navigation
// Get.off(const CallPage());
} catch (e) {}
} else if (message.notification!.title! == 'Order Applied'.tr) {
mySnackbarSuccess("The order has been accepted by another driver.".tr);
} else if (message.notification!.title! == 'Order') {
if (Platform.isAndroid) {
notificationController.showNotification(
message.notification!.title.toString(),
message.notification!.body.toString(),
'order',
'');
}
var myListString = message.data['DriverList'];
// var points = message.data['PolylineJson'];
cancelTripDialog();
break;
var myList = jsonDecode(myListString) as List<dynamic>;
// var myPoints = jsonDecode(points) as List<dynamic>;
driverToken = myList[14].toString();
Get.put(HomeCaptainController()).changeRideId();
update();
Get.to(() => OrderSpeedRequest(), arguments: {
'myListString': myListString,
'DriverList': myList,
// 'PolylineJson': myPoints,
'body': message.notification!.body
});
} 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',
'');
}
case 'VIP Order Accepted':
// This seems to be a notification for the passenger, but if the driver needs to see it:
if (Platform.isAndroid) {
notificationController.showNotification(title, body, 'order', '');
}
// Maybe show a simple snackbar confirmation
mySnackbarSuccess('You accepted the VIP order.'.tr);
break;
case 'message From passenger':
case 'MSG_FROM_PASSENGER':
if (Platform.isAndroid) {
notificationController.showNotification(title, body, 'ding', '');
}
MyDialog().getDialog(title, body, () {
Get.back();
});
break;
case 'token change':
case 'TOKEN_CHANGE':
GoogleSignInHelper.signOut();
break;
case 'face detect':
case 'FACE_DETECT':
if (Platform.isAndroid) {
notificationController.showNotification(title, body, 'tone2', '');
}
String result0 = await faceDetector();
var result = jsonDecode(result0);
MyDialogContent().getDialog(
'Face Detection Result'.tr,
Text(
result['similar'].toString() == 'true'
? 'similar'.tr
: 'not similar'.tr,
style: AppStyle.title,
),
() {
Get.back();
},
);
update();
break;
case 'Hi ,I will go now':
case 'PASSENGER_COMING':
if (Platform.isAndroid) {
notificationController.showNotification(title, body, 'tone2', '');
}
update();
break;
case 'Criminal Document Required':
case 'DOC_REQUIRED':
if (Platform.isAndroid) {
notificationController.showNotification(title, body, 'tone2', '');
}
MyDialog().getDialog(title, 'You should have upload it .'.tr, () {
Get.to(() => const CriminalDocumemtPage());
});
break;
case 'Order Applied':
case 'ORDER_TAKEN':
mySnackbarSuccess("The order has been accepted by another driver.".tr);
break;
default:
Log.print('Received unhandled notification category: $category');
// Optionally show a generic notification
if (Platform.isAndroid) {
notificationController.showNotification(title, body, 'default', '');
}
break;
}
}
@@ -376,380 +282,6 @@ class FirebaseMessagesController extends GetxController {
Get.offAll(HomeCaptain());
}));
}
// Future<dynamic> driverArrivePassengerDialoge() {
// return Get.defaultDialog(
// barrierDismissible: false,
// title: 'Hi ,I Arrive your site'.tr,
// middleText: 'Please go to Car Driver'.tr,
// confirm: MyElevatedButton(
// title: 'Ok I will go now.'.tr,
// onPressed: () {
// FirebaseMessagesController().sendNotificationToPassengerToken(
// 'Hi ,I will go now'.tr,
// 'I will go now'.tr,
// Get.find<MapDriverController>().driverToken, []);
// Get.find<MapPassengerController>()
// .startTimerDriverWaitPassenger5Minute();
// Get.back();
// }));
// }
// late String serviceAccountKeyJson;
// @override
// Future<void> onInit() async {
// super.onInit();
// try {
// // getToken();
// 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');
// }
// }
// void sendNotificationAll(String title, body, tone) async {
// // توكني الحالي (لا أرسل لنفسي)
// final String myToken = box.read(BoxName.tokenFCM) ?? '';
// // اقرأ قائمة كل التوكنات
// final List<String> all =
// List<String>.from(box.read(BoxName.tokens) ?? const []);
// // استبعد توكنك واحذف الفارغ
// final targets = all.where((t) => t.isNotEmpty && t != myToken).toList();
// if (serviceAccountKeyJson.isEmpty) {
// print("🔴 Error: Service Account Key is empty");
// return;
// }
// final accessTokenManager = AccessTokenManager(serviceAccountKeyJson);
// final accessToken = await accessTokenManager.getAccessToken();
// for (final t in targets) {
// // ⚠️ المهم: استخدم t (توكن الهدف)، وليس المتغير myToken
// final response = await http.post(
// Uri.parse(
// 'https://fcm.googleapis.com/v1/projects/ride-b1bd8/messages:send'),
// headers: {
// 'Content-Type': 'application/json',
// 'Authorization': 'Bearer $accessToken',
// },
// body: jsonEncode({
// 'message': {
// 'token': t,
// 'notification': {'title': title, 'body': body},
// 'android': {
// 'priority': 'HIGH', // القيم الصحيحة: HIGH/NORMAL
// 'notification': {'sound': tone},
// // (اختياري) TTL لتجنّب رسائل قديمة
// 'ttl': '30s',
// },
// 'apns': {
// 'headers': {
// 'apns-priority': '10',
// // لو iOS: حدد نوع الدفع
// 'apns-push-type': 'alert',
// },
// 'payload': {
// 'aps': {'sound': tone}
// },
// },
// },
// }),
// );
// if (response.statusCode != 200) {
// // حاول تقرأ الخطأ وتشيل التوكنات التالفة
// _handleV1Error(response, badToken: t);
// await Future.delayed(const Duration(milliseconds: 50)); // تخفيف ضغط
// }
// }
// }
// void _handleV1Error(http.Response res, {required String badToken}) {
// try {
// final body = jsonDecode(res.body);
// final err = body['error']?['status']?.toString() ?? '';
// // أمثلة شائعة:
// if (err.contains('UNREGISTERED') || err.contains('NOT_FOUND')) {
// removeInvalidToken(badToken);
// } else if (err.contains('INVALID_ARGUMENT')) {
// // payload غير صحيح
// print(
// '⚠️ INVALID_ARGUMENT for $badToken: ${body['error']?['message']}');
// } else if (err.contains('RESOURCE_EXHAUSTED') ||
// err.contains('QUOTA_EXCEEDED')) {
// // تجاوزت الحصة—خفّف السرعة/قسّم الإرسال (FCM v1 له حصة/دقيقة)
// // https docs: 600k req/min per project (token bucket)
// print('⏳ Throttled by FCM: slow down sending rate.');
// } else {
// print('FCM v1 error: ${res.statusCode} ${res.body}');
// }
// } catch (_) {
// print('FCM v1 error: ${res.statusCode} ${res.body}');
// }
// }
// void sendNotificationToPassengerToken(
// String title, body, token, List<String> map, String tone,
// {int retryCount = 2}) 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/ride-b1bd8/messages:send'),
// headers: <String, String>{
// 'Content-Type': 'application/json',
// 'Authorization': 'Bearer $accessToken',
// },
// body: jsonEncode({
// 'message': {
// 'token': token,
// 'notification': {
// 'title': title,
// 'body': body,
// },
// 'data': {
// 'passengerList': jsonEncode(map),
// },
// '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 body: ${response.body}');
// } 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(
// const Duration(seconds: 2)); // Optional delay before retrying
// return sendNotificationToPassengerToken(title, body, token, map, tone,
// retryCount: retryCount - 1);
// }
// }
// } catch (e) {
// print('Error sending notification: $e');
// if (retryCount > 0) {
// print('Retrying... Attempts remaining: $retryCount');
// await Future.delayed(
// const Duration(seconds: 2)); // Optional delay before retrying
// return sendNotificationToPassengerToken(title, body, token, map, tone,
// retryCount: retryCount - 1);
// }
// }
// }
// void sendNotificationToPassengerTokenCALL(
// String title, body, token, List<String> map, String tone,
// {int retryCount = 2}) 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/ride-b1bd8/messages:send'),
// headers: <String, String>{
// 'Content-Type': 'application/json',
// 'Authorization': 'Bearer $accessToken',
// },
// body: jsonEncode({
// 'message': {
// 'token': token,
// 'notification': {
// 'title': title,
// 'body': body,
// },
// 'data': {
// 'passengerList': jsonEncode(map),
// },
// '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 body: ${response.body}');
// } 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(
// const Duration(seconds: 2)); // Optional delay before retrying
// return sendNotificationToPassengerTokenCALL(
// title, body, token, map, tone,
// retryCount: retryCount - 1);
// }
// }
// } catch (e) {
// print('Error sending notification: $e');
// if (retryCount > 0) {
// print('Retrying... Attempts remaining: $retryCount');
// await Future.delayed(
// const Duration(seconds: 2)); // Optional delay before retrying
// return sendNotificationToPassengerTokenCALL(
// title, body, token, map, tone,
// retryCount: retryCount - 1);
// }
// }
// }
// Future<void> sendNotificationToDriverMAP(
// String title, String body, String token, List<String> data, String tone,
// {int retryCount = 2}) 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);
// }
// }
// }
// Future<void> removeInvalidToken(String token) async {
// // Remove token from your database/storage
// // This prevents future attempts to send to invalid tokens
// print('Removing invalid token from database: $token');
// // Your database cleanup logic here
// }
}
class OverlayContent extends StatelessWidget {

View File

@@ -1,8 +1,10 @@
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:http/http.dart' as http;
import '../../print.dart';
class NotificationService {
// استبدل هذا الرابط بالرابط الصحيح لملف PHP على السيرفر الخاص بك
// تأكد من أن هذا هو الرابط الصحيح لملف الإرسال
static const String _serverUrl =
'https://syria.intaleq.xyz/intaleq/fcm/send_fcm.php';
@@ -10,8 +12,9 @@ class NotificationService {
required String target,
required String title,
required String body,
required String? category, // <-- [الإضافة الأولى]
String? tone,
List<String>? driverList, // <-- [تعديل 1] : إضافة المتغير الجديد
List<String>? driverList,
bool isTopic = false,
}) async {
try {
@@ -22,14 +25,17 @@ class NotificationService {
'isTopic': isTopic,
};
// نضيف النغمة فقط إذا لم تكن فارغة
if (category != null) {
payload['category'] = category; // <-- [الإضافة الثانية]
}
if (tone != null) {
payload['tone'] = tone;
}
// <-- [تعديل 2] : نضيف قائمة البيانات بعد تشفيرها إلى JSON
if (driverList != null) {
payload['driverList'] = jsonEncode(driverList);
// [مهم] تطبيق السائق يرسل passengerList
payload['passengerList'] = jsonEncode(driverList);
}
final response = await http.post(
@@ -41,15 +47,13 @@ class NotificationService {
);
if (response.statusCode == 200) {
print('✅ Notification sent successfully.');
print('Server Response: ${response.body}');
Log.print('✅ Notification sent successfully.');
} else {
print(
Log.print(
'❌ Failed to send notification. Status code: ${response.statusCode}');
print('Server Error: ${response.body}');
}
} catch (e) {
print('❌ An error occurred while sending notification: $e');
Log.print('❌ An error occurred while sending notification: $e');
}
}
}