25-10-6/1

This commit is contained in:
Hamza-Ayed
2025-10-05 23:45:18 +03:00
parent f5dfe2c0fe
commit de84662e02
18 changed files with 590 additions and 451 deletions

View File

@@ -47,8 +47,8 @@ android {
// For more information, see: https://flutter.dev/to/review-gradle-config. // For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = 29 minSdk = 29
targetSdk = 36 targetSdk = 36
versionCode = 21 versionCode = 22
versionName = '1.0.21' versionName = '1.0.22'
multiDexEnabled = true multiDexEnabled = true
ndk { ndk {
abiFilters "armeabi-v7a", "arm64-v8a" abiFilters "armeabi-v7a", "arm64-v8a"

View File

@@ -16,6 +16,12 @@
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
AA876D08FE53783AD8BF2725 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 39212999DE88888965020906 /* Pods_RunnerTests.framework */; }; AA876D08FE53783AD8BF2725 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 39212999DE88888965020906 /* Pods_RunnerTests.framework */; };
C62456532E928D5900873892 /* tone2.wav in Resources */ = {isa = PBXBuildFile; fileRef = C62456522E928D5900873892 /* tone2.wav */; };
C62456542E928D5900873892 /* ding.wav in Resources */ = {isa = PBXBuildFile; fileRef = C624564E2E928D5900873892 /* ding.wav */; };
C62456552E928D5900873892 /* promo.wav in Resources */ = {isa = PBXBuildFile; fileRef = C624564F2E928D5900873892 /* promo.wav */; };
C62456562E928D5900873892 /* tone1.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = C62456512E928D5900873892 /* tone1.mp3 */; };
C62456572E928D5900873892 /* cancel.wav in Resources */ = {isa = PBXBuildFile; fileRef = C624564D2E928D5900873892 /* cancel.wav */; };
C62456582E928D5900873892 /* start.wav in Resources */ = {isa = PBXBuildFile; fileRef = C62456502E928D5900873892 /* start.wav */; };
C63F78F72E17536F003A6E1F /* Config.plist in Resources */ = {isa = PBXBuildFile; fileRef = C63F78F62E17536F003A6E1F /* Config.plist */; }; C63F78F72E17536F003A6E1F /* Config.plist in Resources */ = {isa = PBXBuildFile; fileRef = C63F78F62E17536F003A6E1F /* Config.plist */; };
C63F78FB2E17553F003A6E1F /* KeychainHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C63F78FA2E17553F003A6E1F /* KeychainHelper.swift */; }; C63F78FB2E17553F003A6E1F /* KeychainHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = C63F78FA2E17553F003A6E1F /* KeychainHelper.swift */; };
C63F78FE2E175599003A6E1F /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C63F78FC2E175599003A6E1F /* Localizable.strings */; }; C63F78FE2E175599003A6E1F /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = C63F78FC2E175599003A6E1F /* Localizable.strings */; };
@@ -73,6 +79,12 @@
ABF3F60EE795EBE3DFBF69F0 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; }; ABF3F60EE795EBE3DFBF69F0 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
BB6C82DBEDDC29FF68D81475 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; BB6C82DBEDDC29FF68D81475 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C08043AFCD4E2A948E0CD137 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; }; C08043AFCD4E2A948E0CD137 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
C624564D2E928D5900873892 /* cancel.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = cancel.wav; sourceTree = "<group>"; };
C624564E2E928D5900873892 /* ding.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = ding.wav; sourceTree = "<group>"; };
C624564F2E928D5900873892 /* promo.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = promo.wav; sourceTree = "<group>"; };
C62456502E928D5900873892 /* start.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = start.wav; sourceTree = "<group>"; };
C62456512E928D5900873892 /* tone1.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = tone1.mp3; sourceTree = "<group>"; };
C62456522E928D5900873892 /* tone2.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = tone2.wav; sourceTree = "<group>"; };
C63F78F62E17536F003A6E1F /* Config.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Config.plist; sourceTree = "<group>"; }; C63F78F62E17536F003A6E1F /* Config.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Config.plist; sourceTree = "<group>"; };
C63F78FA2E17553F003A6E1F /* KeychainHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainHelper.swift; sourceTree = "<group>"; }; C63F78FA2E17553F003A6E1F /* KeychainHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeychainHelper.swift; sourceTree = "<group>"; };
C63F78FD2E175599003A6E1F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; }; C63F78FD2E175599003A6E1F /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
@@ -173,6 +185,12 @@
C63F78F62E17536F003A6E1F /* Config.plist */, C63F78F62E17536F003A6E1F /* Config.plist */,
97C146FA1CF9000F007C117D /* Main.storyboard */, 97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */, 97C146FD1CF9000F007C117D /* Assets.xcassets */,
C624564D2E928D5900873892 /* cancel.wav */,
C624564E2E928D5900873892 /* ding.wav */,
C624564F2E928D5900873892 /* promo.wav */,
C62456502E928D5900873892 /* start.wav */,
C62456512E928D5900873892 /* tone1.mp3 */,
C62456522E928D5900873892 /* tone2.wav */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */, 97C147021CF9000F007C117D /* Info.plist */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
@@ -286,6 +304,12 @@
files = ( files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
C62456532E928D5900873892 /* tone2.wav in Resources */,
C62456542E928D5900873892 /* ding.wav in Resources */,
C62456552E928D5900873892 /* promo.wav in Resources */,
C62456562E928D5900873892 /* tone1.mp3 in Resources */,
C62456572E928D5900873892 /* cancel.wav in Resources */,
C62456582E928D5900873892 /* start.wav in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
C63F78FE2E175599003A6E1F /* Localizable.strings in Resources */, C63F78FE2E175599003A6E1F /* Localizable.strings in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,

BIN
ios/Runner/cancel.wav Normal file

Binary file not shown.

BIN
ios/Runner/ding.wav Normal file

Binary file not shown.

BIN
ios/Runner/promo.wav Normal file

Binary file not shown.

BIN
ios/Runner/start.wav Normal file

Binary file not shown.

BIN
ios/Runner/tone1.mp3 Normal file

Binary file not shown.

BIN
ios/Runner/tone2.wav Normal file

Binary file not shown.

View File

@@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'dart:math'; import 'dart:math';
import 'package:Intaleq/constant/api_key.dart'; import 'package:Intaleq/constant/api_key.dart';
import 'package:Intaleq/controller/firebase/firbase_messge.dart';
import 'package:Intaleq/views/auth/otp_page.dart'; import 'package:Intaleq/views/auth/otp_page.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
@@ -47,33 +48,34 @@ class LoginController extends GetxController {
var dev = ''; var dev = '';
@override @override
void onInit() async { void onInit() async {
await getAppTester(); // await getAppTester();
Log.print('box.read(BoxName.isTest): ${box.read(BoxName.isTest)}'); // Log.print('box.read(BoxName.isTest): ${box.read(BoxName.isTest)}');
box.write(BoxName.countryCode, 'Syria'); box.write(BoxName.countryCode, 'Syria');
FirebaseMessagesController().getToken();
super.onInit(); super.onInit();
} }
getAppTester() async { // getAppTester() async {
var res = await CRUD().get( // var res = await CRUD().get(
link: AppLink.getTesterApp, // link: AppLink.getTesterApp,
payload: {'appPlatform': AppInformation.appName}); // payload: {'appPlatform': AppInformation.appName});
if (res != 'failure') { // if (res != 'failure') {
var d = jsonDecode(res); // var d = jsonDecode(res);
isTest = int.parse(d['message'][0]['isTest'].toString()); // isTest = int.parse(d['message'][0]['isTest'].toString());
box.write(BoxName.isTest, isTest); // box.write(BoxName.isTest, isTest);
update(); // update();
} else { // } else {
box.write(BoxName.isTest, '1'); // box.write(BoxName.isTest, '1');
update(); // update();
return false; // return false;
} // }
} // }
updateAppTester(String appPlatform) async { // updateAppTester(String appPlatform) async {
await CRUD().post( // await CRUD().post(
link: AppLink.updateTesterApp, payload: {'appPlatform': appPlatform}); // link: AppLink.updateTesterApp, payload: {'appPlatform': appPlatform});
} // }
void saveAgreementTerms() { void saveAgreementTerms() {
box.write(BoxName.agreeTerms, 'agreed'); box.write(BoxName.agreeTerms, 'agreed');
@@ -362,7 +364,7 @@ class LoginController extends GetxController {
// var token = await CRUD().get(link: AppLink.getTokens, payload: { // var token = await CRUD().get(link: AppLink.getTokens, payload: {
// 'passengerID': box.read(BoxName.passengerID).toString() // 'passengerID': box.read(BoxName.passengerID).toString()
// }); // });
await updateAppTester(AppInformation.appName); // await updateAppTester(AppInformation.appName);
Get.offAll(() => const MapPagePassenger()); Get.offAll(() => const MapPagePassenger());
} else { } else {

View File

@@ -9,6 +9,7 @@ import 'package:get/get.dart';
import '../../print.dart'; import '../../print.dart';
import '../../views/home/map_page_passenger.dart'; import '../../views/home/map_page_passenger.dart';
import '../firebase/firbase_messge.dart'; import '../firebase/firbase_messge.dart';
import '../firebase/notification_service.dart';
import '../functions/package_info.dart'; import '../functions/package_info.dart';
class OtpVerificationController extends GetxController { class OtpVerificationController extends GetxController {
@@ -94,12 +95,20 @@ class OtpVerificationController extends GetxController {
? Get.find<FirebaseMessagesController>() ? Get.find<FirebaseMessagesController>()
: Get.put(FirebaseMessagesController()); : Get.put(FirebaseMessagesController());
await fcm.sendNotificationToDriverMAP( // await fcm.sendNotificationToDriverMAP(
'token change', // 'token change',
'change device'.tr, // 'change device'.tr,
ptoken.toString(), // ptoken.toString(),
[], // [],
'cancel.wav', // 'cancel',
// );
await NotificationService.sendNotification(
target: ptoken.toString(),
title: 'token change'.tr,
body: 'change device'.tr,
isTopic: false, // Important: this is a token
tone: 'cancel',
driverList: [],
); );
await CRUD().post( await CRUD().post(
link: "${AppLink.seferPaymentServer}/ride/firebase/add.php", link: "${AppLink.seferPaymentServer}/ride/firebase/add.php",

View File

@@ -25,6 +25,7 @@ import '../functions/audio_record1.dart';
import '../home/map_passenger_controller.dart'; import '../home/map_passenger_controller.dart';
import 'access_token.dart'; import 'access_token.dart';
import 'local_notification.dart'; import 'local_notification.dart';
import 'notification_service.dart';
class FirebaseMessagesController extends GetxController { class FirebaseMessagesController extends GetxController {
final fcmToken = FirebaseMessaging.instance; final fcmToken = FirebaseMessaging.instance;
@@ -73,29 +74,6 @@ class FirebaseMessagesController extends GetxController {
? Get.find<NotificationController>() ? Get.find<NotificationController>()
: Get.put(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 { Future getToken() async {
fcmToken.getToken().then((token) { fcmToken.getToken().then((token) {
// Log.print('fcmToken: ${token}'); // Log.print('fcmToken: ${token}');
@@ -202,7 +180,7 @@ class FirebaseMessagesController extends GetxController {
passengerDialog(message.notification!.body!); passengerDialog(message.notification!.body!);
update(); update();
} else if (message.notification!.title! == 'Trip is Begin'.tr) { } else if (message.notification!.title! == 'Trip is Begin') {
if (Platform.isAndroid) { if (Platform.isAndroid) {
notificationController.showNotification( notificationController.showNotification(
'Trip is Begin'.tr, ''.tr, 'start'); 'Trip is Begin'.tr, ''.tr, 'start');
@@ -256,33 +234,60 @@ class FirebaseMessagesController extends GetxController {
// .searchNewDriverAfterRejectingFromDriver(); // .searchNewDriverAfterRejectingFromDriver();
); );
} else if (message.notification!.title! == 'Driver Finish Trip'.tr) { } else if (message.notification!.title! == 'Driver Finish Trip'.tr) {
var myListString = message.data['DriverList']; // الخطوة 1: استقبل البيانات وتحقق من وجودها
Log.print('myListString: ${myListString}'); final rawData = message.data['DriverList'];
var driverList = jsonDecode(myListString) as List<dynamic>; List<dynamic> driverList = []; // ابدأ بقائمة فارغة كإجراء وقائي
Log.print('driverList: ${driverList}');
if (Platform.isAndroid) { // الخطوة 2: قم بفك تشفير البيانات بأمان
notificationController.showNotification( if (rawData != null && rawData is String) {
"Driver Finish Trip".tr, try {
'you will pay to Driver'.tr + ' ${driverList[3].toString()} \$'.tr, driverList = jsonDecode(rawData);
'tone1'); Log.print('Successfully decoded DriverList: $driverList');
} catch (e) {
Log.print('Error decoding DriverList JSON: $e');
// اترك القائمة فارغة في حالة حدوث خطأ
}
} else {
Log.print('Error: DriverList data is null or not a String.');
} }
Get.find<AudioRecorderController>().stopRecording();
if (double.parse(box.read(BoxName.passengerWalletTotal)) < 0) { // الخطوة 3: استخدم البيانات فقط إذا كانت القائمة تحتوي على العناصر المطلوبة
box.write(BoxName.passengerWalletTotal, 0); // هذا يمنع خطأ "RangeError" إذا كانت القائمة أقصر من المتوقع
if (driverList.length >= 4) {
if (Platform.isAndroid) {
notificationController.showNotification(
"Driver Finish Trip".tr,
'${'you will pay to Driver'.tr} ${driverList[3].toString()} \$', // تم تحسين طريقة عرض النص
'tone1');
}
Get.find<AudioRecorderController>().stopRecording();
if ((double.tryParse(
box.read(BoxName.passengerWalletTotal).toString()) ??
0) <
0) {
box.write(BoxName.passengerWalletTotal, 0);
}
Get.find<MapPassengerController>().tripFinishedFromDriver();
NotificationController().showNotification(
'Dont 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');
Get.to(() => RateDriverFromPassenger(), arguments: {
'driverId': driverList[0].toString(),
'rideId': driverList[1].toString(),
'price': driverList[3].toString()
});
} else {
Log.print(
'Error: Decoded driverList does not have enough elements. Received: $driverList');
// هنا يمكنك عرض رسالة خطأ للمستخدم إذا لزم الأمر
} }
print(333);
Get.find<MapPassengerController>().tripFinishedFromDriver();
NotificationController().showNotification(
'Dont 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) { } else if (message.notification!.title! == "Finish Monitor".tr) {
Get.defaultDialog( Get.defaultDialog(
titleStyle: AppStyle.title, titleStyle: AppStyle.title,
@@ -423,12 +428,21 @@ class FirebaseMessagesController extends GetxController {
confirm: MyElevatedButton( confirm: MyElevatedButton(
title: 'Ok I will go now.'.tr, title: 'Ok I will go now.'.tr,
onPressed: () { onPressed: () {
sendNotificationToPassengerToken( // sendNotificationToPassengerToken(
'Hi ,I will go now', // 'Hi ,I will go now',
'I will go now'.tr, // 'I will go now'.tr,
Get.find<MapPassengerController>().driverToken, // Get.find<MapPassengerController>().driverToken,
[], // [],
'ding.wav'); // 'ding');
NotificationService.sendNotification(
target:
Get.find<MapPassengerController>().driverToken.toString(),
title: 'Hi ,I will go now'.tr,
body: 'I will go now'.tr,
isTopic: false, // Important: this is a token
tone: 'ding',
driverList: [],
);
Get.find<MapPassengerController>() Get.find<MapPassengerController>()
.startTimerDriverWaitPassenger5Minute(); .startTimerDriverWaitPassenger5Minute();
@@ -487,57 +501,57 @@ class FirebaseMessagesController extends GetxController {
)); ));
} }
void sendNotificationAll(String title, body, tone) async { // void sendNotificationAll(String title, body, tone) async {
// Get the token you want to subtract. // // Get the token you want to subtract.
String token = box.read(BoxName.tokenFCM); // String token = box.read(BoxName.tokenFCM);
tokens = box.read(BoxName.tokens); // tokens = box.read(BoxName.tokens);
// Subtract the token from the list of tokens. // // Subtract the token from the list of tokens.
tokens.remove(token); // tokens.remove(token);
// Save the list of tokens back to the box. // // Save the list of tokens back to the box.
// box.write(BoxName.tokens, tokens); // // box.write(BoxName.tokens, tokens);
tokens = box.read(BoxName.tokens); // tokens = box.read(BoxName.tokens);
for (var i = 0; i < tokens.length; i++) { // for (var i = 0; i < tokens.length; i++) {
http // http
.post( // .post(
Uri.parse('https://fcm.googleapis.com/fcm/send'), // Uri.parse('https://fcm.googleapis.com/fcm/send'),
headers: <String, String>{ // headers: <String, String>{
'Content-Type': 'application/json', // 'Content-Type': 'application/json',
'Authorization': 'key=${AK.serverAPI}' // 'Authorization': 'key=${AK.serverAPI}'
}, // },
body: jsonEncode({ // body: jsonEncode({
'message': { // 'message': {
'token': token, // 'token': token,
'notification': { // 'notification': {
'title': title, // 'title': title,
'body': body, // 'body': body,
}, // },
// 'data': { // // 'data': {
// 'DriverList': jsonEncode(data), // // 'DriverList': jsonEncode(data),
// }, // // },
'android': { // 'android': {
'priority': 'HIGH ', // Set priority to high // 'priority': 'HIGH ', // Set priority to high
'notification': { // 'notification': {
'sound': tone, // 'sound': tone,
}, // },
}, // },
'apns': { // 'apns': {
'headers': { // 'headers': {
'apns-priority': '10', // Set APNs priority to 10 // 'apns-priority': '10', // Set APNs priority to 10
}, // },
'payload': { // 'payload': {
'aps': { // 'aps': {
'sound': tone, // 'sound': tone,
}, // },
}, // },
}, // },
}, // },
}), // }),
) // )
.whenComplete(() {}) // .whenComplete(() {})
.catchError((e) {}); // .catchError((e) {});
} // }
} // }
// for (var i = 0; i < tokens.length; i++) { // for (var i = 0; i < tokens.length; i++) {
// http // http
@@ -566,166 +580,166 @@ class FirebaseMessagesController extends GetxController {
// } // }
// } // }
late String serviceAccountKeyJson; // 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"}'; // '{"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 @override
Future<void> onInit() async { Future<void> onInit() async {
super.onInit(); super.onInit();
try { // try {
var encryptedKey = Env.privateKeyFCM; // // var encryptedKey = Env.privateKeyFCM;
// Log.print('encryptedKey: ${encryptedKey}'); // // // Log.print('encryptedKey: ${encryptedKey}');
serviceAccountKeyJson = // // serviceAccountKeyJson =
EncryptionHelper.instance.decryptData(encryptedKey); // // EncryptionHelper.instance.decryptData(encryptedKey);
// Log.print('serviceAccountKeyJson: ${serviceAccountKeyJson}'); // // Log.print('serviceAccountKeyJson: ${serviceAccountKeyJson}');
} catch (e) { // } catch (e) {
print('🔴 Error decrypting FCM key: $e'); // print('🔴 Error decrypting FCM key: $e');
} // }
} }
Future<void> sendNotificationToDriverMAP( // Future<void> sendNotificationToDriverMAP(
String title, String body, String token, List<String> data, String tone, // String title, String body, String token, List<String> data, String tone,
{int retryCount = 1}) async { // {int retryCount = 1}) async {
try { // try {
if (serviceAccountKeyJson.isEmpty) { // if (serviceAccountKeyJson.isEmpty) {
print("🔴 Error: Service Account Key is empty"); // print("🔴 Error: Service Account Key is empty");
return; // return;
} // }
// Initialize AccessTokenManager // // Initialize AccessTokenManager
final accessTokenManager = AccessTokenManager(serviceAccountKeyJson); // final accessTokenManager = AccessTokenManager(serviceAccountKeyJson);
// Log.print( // // Log.print(
// 'accessTokenManager: ${accessTokenManager.serviceAccountJsonKey}'); // // 'accessTokenManager: ${accessTokenManager.serviceAccountJsonKey}');
// Obtain an OAuth 2.0 access token // // Obtain an OAuth 2.0 access token
final accessToken = await accessTokenManager.getAccessToken(); // final accessToken = await accessTokenManager.getAccessToken();
// Log.print('accessToken: ${accessToken}'); // // Log.print('accessToken: ${accessToken}');
// Send the notification // // Send the notification
final response = await http.post( // final response = await http.post(
Uri.parse( // Uri.parse(
'https://fcm.googleapis.com/v1/projects/intaleq-d48a7/messages:send'), // 'https://fcm.googleapis.com/v1/projects/intaleq-d48a7/messages:send'),
headers: <String, String>{ // headers: <String, String>{
'Content-Type': 'application/json', // 'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken', // 'Authorization': 'Bearer $accessToken',
}, // },
body: jsonEncode({ // body: jsonEncode({
'message': { // 'message': {
'token': token, // 'token': token,
'notification': { // 'notification': {
'title': title, // 'title': title,
'body': body, // 'body': body,
}, // },
'data': { // 'data': {
'DriverList': jsonEncode(data), // 'DriverList': jsonEncode(data),
}, // },
'android': { // 'android': {
'priority': 'HIGH ', // Set priority to high // 'priority': 'HIGH ', // Set priority to high
'notification': { // 'notification': {
'sound': tone, // 'sound': tone,
}, // },
}, // },
'apns': { // 'apns': {
'headers': { // 'headers': {
'apns-priority': '10', // Set APNs priority to 10 // 'apns-priority': '10', // Set APNs priority to 10
}, // },
'payload': { // 'payload': {
'aps': { // 'aps': {
'sound': tone, // 'sound': tone,
}, // },
}, // },
}, // },
}, // },
}), // }),
); // );
if (response.statusCode == 200) { // if (response.statusCode == 200) {
print( // print(
'Notification sent successfully. Status code: ${response.statusCode}'); // 'Notification sent successfully. Status code: ${response.statusCode}');
// print('Response token: ${token}'); // // print('Response token: ${token}');
} else { // } else {
print( // print(
'Failed to send notification. Status code: ${response.statusCode}'); // 'Failed to send notification. Status code: ${response.statusCode}');
print('Response body: ${response.body}'); // print('Response body: ${response.body}');
if (retryCount > 0) { // if (retryCount > 0) {
print('Retrying... Attempts remaining: $retryCount'); // print('Retrying... Attempts remaining: $retryCount');
await Future.delayed( // await Future.delayed(
Duration(seconds: 2)); // Optional delay before retrying // Duration(seconds: 2)); // Optional delay before retrying
return sendNotificationToDriverMAP(title, body, token, data, tone, // return sendNotificationToDriverMAP(title, body, token, data, tone,
retryCount: retryCount - 1); // retryCount: retryCount - 1);
} // }
} // }
} catch (e) { // } catch (e) {
print('Error sending notification: $e'); // print('Error sending notification: $e');
if (retryCount > 0) { // if (retryCount > 0) {
print('Retrying... Attempts remaining: $retryCount'); // print('Retrying... Attempts remaining: $retryCount');
await Future.delayed( // await Future.delayed(
Duration(seconds: 2)); // Optional delay before retrying // Duration(seconds: 2)); // Optional delay before retrying
return sendNotificationToDriverMAP(title, body, token, data, tone, // return sendNotificationToDriverMAP(title, body, token, data, tone,
retryCount: retryCount - 1); // retryCount: retryCount - 1);
} // }
} // }
} // }
void sendNotificationToPassengerToken( // void sendNotificationToPassengerToken(
String title, body, token, List<String> map, String tone) async { // String title, body, token, List<String> map, String tone) async {
try { // try {
if (serviceAccountKeyJson.isEmpty) { // if (serviceAccountKeyJson.isEmpty) {
print("🔴 Error: Service Account Key is empty"); // print("🔴 Error: Service Account Key is empty");
return; // return;
} // }
// Initialize AccessTokenManager // // Initialize AccessTokenManager
final accessTokenManager = AccessTokenManager(serviceAccountKeyJson); // final accessTokenManager = AccessTokenManager(serviceAccountKeyJson);
// Obtain an OAuth 2.0 access token // // Obtain an OAuth 2.0 access token
final accessToken = await accessTokenManager.getAccessToken(); // final accessToken = await accessTokenManager.getAccessToken();
// Log.print('accessToken: ${accessToken}'); // // Log.print('accessToken: ${accessToken}');
// Send the notification // // Send the notification
final response = await http.post( // final response = await http.post(
Uri.parse( // Uri.parse(
'https://fcm.googleapis.com/v1/projects/intaleq-d48a7/messages:send'), // 'https://fcm.googleapis.com/v1/projects/intaleq-d48a7/messages:send'),
headers: <String, String>{ // headers: <String, String>{
'Content-Type': 'application/json', // 'Content-Type': 'application/json',
'Authorization': 'Bearer $accessToken', // 'Authorization': 'Bearer $accessToken',
}, // },
body: jsonEncode({ // body: jsonEncode({
'message': { // 'message': {
'token': token, // 'token': token,
'notification': { // 'notification': {
'title': title, // 'title': title,
'body': body, // 'body': body,
}, // },
'android': { // 'android': {
'priority': 'HIGH ', // Set priority to high // 'priority': 'HIGH ', // Set priority to high
'notification': { // 'notification': {
'sound': tone, // 'sound': tone,
}, // },
}, // },
'apns': { // 'apns': {
'headers': { // 'headers': {
'apns-priority': '10', // Set APNs priority to 10 // 'apns-priority': '10', // Set APNs priority to 10
}, // },
'payload': { // 'payload': {
'aps': { // 'aps': {
'sound': tone, // 'sound': tone,
}, // },
}, // },
}, // },
}, // },
}), // }),
); // );
if (response.statusCode == 200) { // if (response.statusCode == 200) {
print('✅ Notification sent successfully!'); // print('✅ Notification sent successfully!');
} else { // } else {
print( // print(
'🔴 Failed to send notification. Status code: ${response.statusCode}'); // '🔴 Failed to send notification. Status code: ${response.statusCode}');
print('Response body: ${response.body}'); // print('Response body: ${response.body}');
} // }
} catch (e) { // } catch (e) {
print('🔴 Error sending notification: $e'); // print('🔴 Error sending notification: $e');
} // }
} // }
} }
class DriverTipWidget extends StatelessWidget { class DriverTipWidget extends StatelessWidget {

View File

@@ -6,66 +6,50 @@ class NotificationService {
static const String _serverUrl = static const String _serverUrl =
'https://syria.intaleq.xyz/intaleq/fcm/send_fcm.php'; 'https://syria.intaleq.xyz/intaleq/fcm/send_fcm.php';
/// Sends a notification via your backend server.
///
/// [target]: The device token or the topic name.
/// [title]: The notification title.
/// [body]: The notification body.
/// [isTopic]: Set to true if the target is a topic, false if it's a device token.
static Future<void> sendNotification({ static Future<void> sendNotification({
required String target, required String target,
required String title, required String title,
required String body, required String body,
String? tone,
List<String>? driverList, // <-- [تعديل 1] : إضافة المتغير الجديد
bool isTopic = false, bool isTopic = false,
}) async { }) async {
try { try {
final Map<String, dynamic> payload = {
'target': target,
'title': title,
'body': body,
'isTopic': isTopic,
};
// نضيف النغمة فقط إذا لم تكن فارغة
if (tone != null) {
payload['tone'] = tone;
}
// <-- [تعديل 2] : نضيف قائمة البيانات بعد تشفيرها إلى JSON
if (driverList != null) {
payload['driverList'] = jsonEncode(driverList);
}
final response = await http.post( final response = await http.post(
Uri.parse(_serverUrl), Uri.parse(_serverUrl),
headers: { headers: {
'Content-Type': 'application/json; charset=UTF-8', 'Content-Type': 'application/json; charset=UTF-8',
}, },
body: jsonEncode({ body: jsonEncode(payload),
'target': target,
'title': title,
'body': body,
'isTopic': isTopic,
}),
); );
if (response.statusCode == 200) { if (response.statusCode == 200) {
print('Notification sent successfully.'); print('Notification sent successfully.');
print('Server Response: ${response.body}'); print('Server Response: ${response.body}');
} else { } else {
print( print(
'Failed to send notification. Status code: ${response.statusCode}'); 'Failed to send notification. Status code: ${response.statusCode}');
print('Server Error: ${response.body}'); print('Server Error: ${response.body}');
} }
} catch (e) { } catch (e) {
print('An error occurred while sending notification: $e'); print('An error occurred while sending notification: $e');
} }
} }
} }
// --- Example of how to use it ---
// To send to a specific driver (using their token)
void sendToSpecificDriver() {
String driverToken =
'bk3RNwTe3H0:CI2k_HHwgIpoDKCI5oT...'; // The driver's FCM token
NotificationService.sendNotification(
target: driverToken,
title: 'New Trip Request!',
body: 'A passenger is waiting for you.',
isTopic: false, // Important: this is a token
);
}
// To send to all drivers (using a topic)
void sendToAllDrivers() {
NotificationService.sendNotification(
target: 'drivers', // The name of the topic
title: 'Important Announcement',
body: 'Please update your app to the latest version.',
isTopic: true, // Important: this is a topic
);
}

View File

@@ -47,6 +47,7 @@ import '../../views/widgets/elevated_btn.dart';
import '../../views/widgets/error_snakbar.dart'; import '../../views/widgets/error_snakbar.dart';
import '../../views/widgets/mydialoug.dart'; import '../../views/widgets/mydialoug.dart';
import '../firebase/firbase_messge.dart'; import '../firebase/firbase_messge.dart';
import '../firebase/notification_service.dart';
import '../functions/audio_record1.dart'; import '../functions/audio_record1.dart';
import '../functions/crud.dart'; import '../functions/crud.dart';
import '../functions/launch.dart'; import '../functions/launch.dart';
@@ -984,12 +985,12 @@ class MapPassengerController extends GetxController {
box.write(BoxName.passengerWalletTotal, '0'); box.write(BoxName.passengerWalletTotal, '0');
update(); update();
if (box.read(BoxName.parentTripSelected) == true) { if (box.read(BoxName.parentTripSelected) == true) {
firebaseMessagesController.sendNotificationToPassengerToken( NotificationService.sendNotification(
"Finish Monitor".tr, target: box.read(BoxName.tokenParent),
"Finish Monitor".tr, title: "Finish Monitor".tr,
box.read(BoxName.tokenParent), body: 'Finish Monitor'.tr,
[], isTopic: false, // Important: this is a token
'order1.wav', tone: 'tone1',
); );
box.write(BoxName.parentTripSelected, false); box.write(BoxName.parentTripSelected, false);
box.remove(BoxName.tokenParent); box.remove(BoxName.tokenParent);
@@ -1396,28 +1397,6 @@ class MapPassengerController extends GetxController {
'distance': distance.toStringAsFixed(1), 'distance': distance.toStringAsFixed(1),
'duration': duration.toStringAsFixed(1), 'duration': duration.toStringAsFixed(1),
}); });
if (AppLink.endPoint != AppLink.IntaleqCairoServer) {
CRUD().post(
link: '${AppLink.endPoint}/notificationCaptain/addWaitingRide.php',
payload: {
'id': rideId.toString(),
'start_location':
'${data[0]["start_location"]['lat']},${data[0]["start_location"]['lng']}',
'end_location':
'${data[0]["end_location"]['lat']},${data[0]["end_location"]['lng']}',
"date": DateTime.now().toString(),
"time": DateTime.now().toString(),
"price": totalPassenger.toStringAsFixed(2),
'passenger_id': box.read(BoxName.passengerID).toString(),
'status': 'waiting',
'carType': box.read(BoxName.carType),
'passengerRate': passengerRate.toStringAsFixed(2),
'price_for_passenger': totalME.toStringAsFixed(2),
'distance': distance.toStringAsFixed(1),
'duration': duration.toStringAsFixed(0),
});
}
} }
// Future<void> confirmRideForAllDriverAvailable1() async { // Future<void> confirmRideForAllDriverAvailable1() async {
@@ -1578,7 +1557,7 @@ class MapPassengerController extends GetxController {
// rideId, // rideId,
// driverData['token'].toString(), // driverData['token'].toString(),
// body, // body,
// 'order.wav', // 'order',
// ); // );
// } // }
// } // }
@@ -1721,7 +1700,7 @@ class MapPassengerController extends GetxController {
// rideId.toString(), // rideId.toString(),
// dataCarsLocationByPassenger['message'][i]['token'].toString(), // dataCarsLocationByPassenger['message'][i]['token'].toString(),
// body, // body,
// 'order.wav'); // 'order');
// } // }
} }
@@ -1750,7 +1729,7 @@ class MapPassengerController extends GetxController {
// Log.print('rideStatusDelayed == Apply: $rideStatusDelayed'); // Log.print('rideStatusDelayed == Apply: $rideStatusDelayed');
// // todo play sound // // todo play sound
// Get.find<AudioRecorderController>() // Get.find<AudioRecorderController>()
// .playSoundFromAssets('assets/start.wav'); // .playSoundFromAssets('assets/start');
// timer.cancel(); // Stop the current timer // timer.cancel(); // Stop the current timer
// await getUpdatedRideForDriverApply(rideId); // await getUpdatedRideForDriverApply(rideId);
// shouldFetch = false; // Stop further fetches // shouldFetch = false; // Stop further fetches
@@ -2000,12 +1979,19 @@ class MapPassengerController extends GetxController {
Future.delayed(const Duration(microseconds: 10)); Future.delayed(const Duration(microseconds: 10));
final body = constructNotificationBody(driverData); final body = constructNotificationBody(driverData);
Log.print('body:ww $body'); Log.print('body:ww $body');
firebaseMessagesController.sendNotificationToDriverMAP( // firebaseMessagesController.sendNotificationToDriverMAP(
'Order', // without tr since background not valid // 'Order', // without tr since background not valid
endNameAddress, // endNameAddress,
(driverData['token'].toString()), // (driverData['token'].toString()),
body, // body,
'order.wav'); // 'order');
NotificationService.sendNotification(
target: (driverData['token'].toString()),
title: 'Order',
body: endNameAddress,
isTopic: false, // Important: this is a token
tone: 'tone1',
driverList: body);
} }
} }
} }
@@ -2049,12 +2035,19 @@ class MapPassengerController extends GetxController {
// Log.print('body:ww ${body}'); // Log.print('body:ww ${body}');
Log.print( Log.print(
'[DEBUG] Sending to driver: ${driverData['driver_id']}, token: ${driverData['token']}'); '[DEBUG] Sending to driver: ${driverData['driver_id']}, token: ${driverData['token']}');
firebaseMessagesController.sendNotificationToDriverMAP( // firebaseMessagesController.sendNotificationToDriverMAP(
'Order', // without tr since background not valid // 'Order', // without tr since background not valid
endNameAddress, // endNameAddress,
(driverData['token'].toString()), // (driverData['token'].toString()),
body, // body,
'order.wav'); // 'order');
NotificationService.sendNotification(
target: (driverData['token'].toString()),
title: 'Order',
body: endNameAddress,
isTopic: false, // Important: this is a token
tone: 'tone1',
driverList: body);
} }
} }
} }
@@ -2146,9 +2139,10 @@ class MapPassengerController extends GetxController {
} else if (rideStatusDelayed == 'Apply' || } else if (rideStatusDelayed == 'Apply' ||
rideStatusDelayed == 'Applied') { rideStatusDelayed == 'Applied') {
isApplied = true; isApplied = true;
timer.cancel();
rideAppliedFromDriver(isApplied);
// timer.cancel(); // timer.cancel();
rideAppliedFromDriver(isApplied);
timer.cancel();
// Close stream after applying // Close stream after applying
} else if (attemptCounter >= maxAttempts || } else if (attemptCounter >= maxAttempts ||
rideStatusDelayed == 'waiting') { rideStatusDelayed == 'waiting') {
@@ -2188,7 +2182,7 @@ class MapPassengerController extends GetxController {
}); });
} }
rideAppliedFromDriver(bool isApplied) async { Future<void> rideAppliedFromDriver(bool isApplied) async {
await getUpdatedRideForDriverApply(rideId); await getUpdatedRideForDriverApply(rideId);
NotificationController().showNotification( NotificationController().showNotification(
'Accepted Ride', 'Accepted Ride',
@@ -2310,12 +2304,20 @@ class MapPassengerController extends GetxController {
} }
// driversToken.remove(driverToken); // driversToken.remove(driverToken);
// for (var i = 1; i < driversToken.length; i++) { // for (var i = 1; i < driversToken.length; i++) {
firebaseMessagesController.sendNotificationToDriverMAP( // firebaseMessagesController.sendNotificationToDriverMAP(
'Order Accepted', // 'Order Accepted',
'$driverName${'Accepted your order'.tr}', // '$driverName${'Accepted your order'.tr}',
driverToken.toString(), // driverToken.toString(),
[], // [],
'start.wav', // 'start',
// );
NotificationService.sendNotification(
target: driverToken.toString(),
title: 'Order Accepted',
body: '$driverName${'Accepted your order'.tr}',
isTopic: false, // Important: this is a token
tone: 'tone1',
// driverList: body,
); );
// } // }
// } // }
@@ -3054,12 +3056,20 @@ class MapPassengerController extends GetxController {
var tokenParent = (res1['data'][0]['token']); var tokenParent = (res1['data'][0]['token']);
Get.snackbar("The invitation was sent successfully".tr, '', Get.snackbar("The invitation was sent successfully".tr, '',
backgroundColor: AppColor.greenColor); backgroundColor: AppColor.greenColor);
firebaseMessagesController.sendNotificationToPassengerToken( // firebaseMessagesController.sendNotificationToPassengerToken(
"Trip Monitoring".tr, // "Trip Monitoring".tr,
"Trip Monitoring".tr, // "Trip Monitoring".tr,
tokenParent, // tokenParent,
[rideId, driverId], // [rideId, driverId],
'order1.wav', // 'order1',
// );
NotificationService.sendNotification(
target: tokenParent.toString(),
title: "Trip Monitoring".tr,
body: "Trip Monitoring".tr,
isTopic: false, // Important: this is a token
tone: 'tone1',
driverList: [rideId, driverId],
); );
box.write(BoxName.parentTripSelected, true); box.write(BoxName.parentTripSelected, true);
box.write(BoxName.tokenParent, tokenParent); box.write(BoxName.tokenParent, tokenParent);
@@ -3326,14 +3336,21 @@ class MapPassengerController extends GetxController {
changeCancelRidePageShow(); changeCancelRidePageShow();
if (rideId != 'yet') { if (rideId != 'yet') {
Log.print('cancelRide: 1'); Log.print('cancelRide: 1');
await firebaseMessagesController.sendNotificationToDriverMAP( // await firebaseMessagesController.sendNotificationToDriverMAP(
'Cancel Trip', // 'Cancel Trip',
'Trip Cancelled'.tr, // 'Trip Cancelled'.tr,
driverToken.toString(), // driverToken.toString(),
[], // [],
'cancel.wav', // 'cancel',
// );
await NotificationService.sendNotification(
target: driverToken.toString(),
title: 'Cancel Trip'.tr,
body: 'Cancel Trip'.tr,
isTopic: false, // Important: this is a token
tone: 'tone1',
driverList: [],
); );
await Future.wait([ await Future.wait([
CRUD().post(link: AppLink.updateRides, payload: { CRUD().post(link: AppLink.updateRides, payload: {
"id": rideId.toString(), // Convert to String "id": rideId.toString(), // Convert to String
@@ -5713,37 +5730,67 @@ class MapPassengerController extends GetxController {
timeSelected); timeSelected);
// Optionally, set up local notification or send a push notification // Optionally, set up local notification or send a push notification
await firebaseMessagesController.sendNotificationToDriverMAP( // await firebaseMessagesController.sendNotificationToDriverMAP(
'OrderVIP', // 'OrderVIP',
rideId.toString(), // rideId.toString(),
// (driver['token'].toString()),
// [
// id,
// rideId,
// driver['id'],
// passengerLocation.latitude.toString(),
// startNameAddress.toString(),
// passengerLocation.longitude.toString(),
// (box.read(BoxName.name).toString().split(' ')[0]).toString(),
// box.read(BoxName.passengerID).toString(),
// box.read(BoxName.phone).toString(),
// box.read(BoxName.email).toString(),
// box.read(BoxName.passengerPhotoUrl).toString(),
// box.read(BoxName.tokenFCM).toString(),
// (driver['token'].toString()),
// ],
// 'order');
await NotificationService.sendNotification(
target: driver['token'].toString(),
title: 'OrderVIP',
body: '$rideId - VIP Trip',
isTopic: false, // Important: this is a token
tone: 'tone1',
driverList: [
id,
rideId,
driver['id'],
passengerLocation.latitude.toString(),
startNameAddress.toString(),
passengerLocation.longitude.toString(),
(box.read(BoxName.name).toString().split(' ')[0]).toString(),
box.read(BoxName.passengerID).toString(),
box.read(BoxName.phone).toString(),
box.read(BoxName.email).toString(),
box.read(BoxName.passengerPhotoUrl).toString(),
box.read(BoxName.tokenFCM).toString(),
(driver['token'].toString()), (driver['token'].toString()),
[ ],
id, );
rideId,
driver['id'],
passengerLocation.latitude.toString(),
startNameAddress.toString(),
passengerLocation.longitude.toString(),
(box.read(BoxName.name).toString().split(' ')[0]).toString(),
box.read(BoxName.passengerID).toString(),
box.read(BoxName.phone).toString(),
box.read(BoxName.email).toString(),
box.read(BoxName.passengerPhotoUrl).toString(),
box.read(BoxName.tokenFCM).toString(),
(driver['token'].toString()),
],
'order.wav');
if (response['message'] == "Trip updated successfully") { if (response['message'] == "Trip updated successfully") {
mySnackbarSuccess("Trip updated successfully".tr); mySnackbarSuccess("Trip updated successfully".tr);
Log.print( Log.print(
'previous_driver_token: ${response['previous_driver_token']}'); 'previous_driver_token: ${response['previous_driver_token']}');
firebaseMessagesController.sendNotificationToDriverMAP( // firebaseMessagesController.sendNotificationToDriverMAP(
'Order VIP Canceld'.tr, // 'Order VIP Canceld'.tr,
'Passenger cancel order'.tr, // 'Passenger cancel order'.tr,
response['previous_driver_token'].toString(), // response['previous_driver_token'].toString(),
[], // [],
'cancel.wav', // 'cancel',
// );
await NotificationService.sendNotification(
target: response['previous_driver_token'].toString(),
title: 'Order VIP Canceld'.tr,
body: 'Passenger cancel order'.tr,
isTopic: false, // Important: this is a token
tone: 'cancel',
driverList: [],
); );
} }
// data = []; // data = [];
@@ -5767,7 +5814,7 @@ class MapPassengerController extends GetxController {
// 'Passenger cancel order'.tr, // 'Passenger cancel order'.tr,
// token, // token,
// [], // [],
// 'cancel.wav', // 'cancel',
// ); // );
var res = await CRUD() var res = await CRUD()
.post(link: AppLink.cancelMishwari, payload: {'id': tripId}); .post(link: AppLink.cancelMishwari, payload: {'id': tripId});
@@ -5778,12 +5825,20 @@ class MapPassengerController extends GetxController {
} }
sendToDriverAgain(String token) { sendToDriverAgain(String token) {
firebaseMessagesController.sendNotificationToDriverMAP( // firebaseMessagesController.sendNotificationToDriverMAP(
'Order VIP Canceld'.tr, // 'Order VIP Canceld'.tr,
'Passenger cancel order'.tr, // 'Passenger cancel order'.tr,
token, // token,
[], // [],
'cancel.wav', // 'cancel',
// );
NotificationService.sendNotification(
target: token.toString(),
title: 'Order VIP Canceld'.tr,
body: 'Passenger cancel order'.tr,
isTopic: false, // Important: this is a token
tone: 'cancel',
driverList: [],
); );
} }

View File

@@ -7,6 +7,7 @@ import '../../constant/box_name.dart';
import '../../constant/links.dart'; import '../../constant/links.dart';
import '../../main.dart'; import '../../main.dart';
import '../../views/widgets/mydialoug.dart'; import '../../views/widgets/mydialoug.dart';
import '../firebase/notification_service.dart';
import '../functions/crud.dart'; import '../functions/crud.dart';
class PassengerNotificationController extends GetxController { class PassengerNotificationController extends GetxController {
@@ -47,12 +48,20 @@ class PassengerNotificationController extends GetxController {
'title': title, 'title': title,
'body': body, 'body': body,
}); });
Get.find<FirebaseMessagesController>().sendNotificationToPassengerToken( // Get.find<FirebaseMessagesController>().sendNotificationToPassengerToken(
title, // title,
body, // body,
'token', // 'token',
[], // [],
'iphone_ringtone.wav', // 'iphone_ringtone',
// );
await NotificationService.sendNotification(
target: 'token'.toString(),
title: title,
body: body.tr,
isTopic: false, // Important: this is a token
tone: 'cancel',
driverList: [],
); );
} }

View File

@@ -19,6 +19,7 @@ import '../../constant/info.dart';
import '../../constant/links.dart'; import '../../constant/links.dart';
import '../../main.dart'; import '../../main.dart';
import '../../print.dart'; import '../../print.dart';
import '../firebase/notification_service.dart';
import '../functions/crud.dart'; import '../functions/crud.dart';
import '../functions/encrypt_decrypt.dart'; import '../functions/encrypt_decrypt.dart';
import '../functions/toast.dart'; import '../functions/toast.dart';
@@ -134,13 +135,23 @@ class PaymentController extends GetxController {
}); });
if (res != 'failure') { if (res != 'failure') {
Get.find<FirebaseMessagesController>().sendNotificationToDriverMAP( // Get.find<FirebaseMessagesController>().sendNotificationToDriverMAP(
'Cancel', // 'Cancel',
'Trip Cancelled. The cost of the trip will be added to your wallet.' // 'Trip Cancelled. The cost of the trip will be added to your wallet.'
.tr, // .tr,
Get.find<MapPassengerController>().driverToken, // Get.find<MapPassengerController>().driverToken,
[], // [],
'cancel.wav', // 'cancel',
// );
await NotificationService.sendNotification(
target: Get.find<MapPassengerController>().driverToken.toString(),
title: 'Cancel',
body:
'Trip Cancelled. The cost of the trip will be added to your wallet.'
.tr,
isTopic: false, // Important: this is a token
tone: 'cancel',
driverList: [],
); );
} }
var paymentTokenWaitPassenger1 = var paymentTokenWaitPassenger1 =

View File

@@ -10,6 +10,7 @@ import 'package:Intaleq/views/home/map_page_passenger.dart';
import 'package:Intaleq/views/widgets/elevated_btn.dart'; import 'package:Intaleq/views/widgets/elevated_btn.dart';
import '../firebase/firbase_messge.dart'; import '../firebase/firbase_messge.dart';
import '../firebase/notification_service.dart';
import '../payment/payment_controller.dart'; import '../payment/payment_controller.dart';
// import '../home/captin/home_captain_controller.dart'; // import '../home/captin/home_captain_controller.dart';
@@ -70,12 +71,21 @@ class RateController extends GetxController {
'token': token1, 'token': token1,
}); });
if (res != 'failure') { if (res != 'failure') {
Get.find<FirebaseMessagesController>().sendNotificationToDriverMAP( // Get.find<FirebaseMessagesController>().sendNotificationToDriverMAP(
'You Have Tips'.tr, // 'You Have Tips'.tr,
'${'${tip.toString()}\$${' tips\nTotal is'.tr}'} ${tip + (Get.find<MapPassengerController>().totalPassenger)}', // '${'${tip.toString()}\$${' tips\nTotal is'.tr}'} ${tip + (Get.find<MapPassengerController>().totalPassenger)}',
Get.find<MapPassengerController>().driverToken.toString(), // Get.find<MapPassengerController>().driverToken.toString(),
[], // [],
'ding.wav', // 'ding',
// );
await NotificationService.sendNotification(
target: Get.find<MapPassengerController>().driverToken.toString(),
title: 'You Have Tips',
body:
'${'${tip.toString()}\$${' tips\nTotal is'.tr}'} ${tip + (Get.find<MapPassengerController>().totalPassenger)}',
isTopic: false, // Important: this is a token
tone: 'ding',
driverList: [],
); );
} }
} }

View File

@@ -9,6 +9,7 @@ import 'package:flutter/services.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import '../../../constant/box_name.dart'; import '../../../constant/box_name.dart';
import '../../../controller/firebase/notification_service.dart';
import '../../../controller/functions/launch.dart'; import '../../../controller/functions/launch.dart';
import '../../widgets/my_textField.dart'; import '../../widgets/my_textField.dart';
@@ -262,12 +263,20 @@ class ApplyOrderWidget extends StatelessWidget {
padding: const EdgeInsets.only(bottom: 8.0), padding: const EdgeInsets.only(bottom: 8.0),
child: ElevatedButton( child: ElevatedButton(
onPressed: () { onPressed: () {
firebaseMessagesController.sendNotificationToDriverMAP( // firebaseMessagesController.sendNotificationToDriverMAP(
'message From passenger', // 'message From passenger',
message.tr, // message.tr,
controller.driverToken.toString(), // controller.driverToken.toString(),
[], // [],
'ding.wav', // 'ding',
// );
NotificationService.sendNotification(
target: controller.driverToken.toString(),
title: 'message From passenger',
body: message.tr, // Make sure to translate the message
isTopic: false, // Important: this is a token
tone: 'ding',
driverList: [],
); );
Get.back(); Get.back();
}, },
@@ -295,12 +304,20 @@ class ApplyOrderWidget extends StatelessWidget {
IconButton( IconButton(
onPressed: () { onPressed: () {
if (controller.messagesFormKey.currentState!.validate()) { if (controller.messagesFormKey.currentState!.validate()) {
firebaseMessagesController.sendNotificationToDriverMAP( // firebaseMessagesController.sendNotificationToDriverMAP(
'message From passenger', // 'message From passenger',
controller.messageToDriver.text, // controller.messageToDriver.text,
controller.driverToken, // controller.driverToken,
[], // [],
'ding.wav', // 'ding',
// );
NotificationService.sendNotification(
target: controller.driverToken.toString(),
title: 'message From passenger',
body: controller.messageToDriver.text,
isTopic: false, // Important: this is a token
tone: 'ding',
driverList: [],
); );
controller.messageToDriver.clear(); controller.messageToDriver.clear();
Get.back(); Get.back();

View File

@@ -129,13 +129,17 @@ class TestPage extends StatelessWidget {
body: Center( body: Center(
child: TextButton( child: TextButton(
onPressed: () async { onPressed: () async {
var token = var token = (box.read(BoxName.tokenFCM).toString());
'e4t5mB-WTsyhi2M0v5AOAy:APA91bGmQG8gcitcJB7x69oHCweCn44NdljP5ZVlO1IK62w62Gac4dCIjE3SMFPV6YcFdTMQrRHE1BXnbktEM19JE4xjcEyLz-GwC1HrCbDl2X24d4PfrPQ'; Log.print(
'box.read(BoxName.tokenFCM).toString(): ${box.read(BoxName.tokenFCM).toString()}');
// 'e-EE5Z5Fn0x5s6EYbtgT6f:APA91bHBTxkbdljuvDF0iPhso58r7fCwGh-WcYh3CYfUJEShUKFcQf496Xc5E6LHqRFKfOQBxYrWSdLO8d9gLbL-IdgyDuZ7jNUjzvrcV_YmagDtgz7-UNw';
// 'fdN1o8akwURHj47wvShC4T:APA91bFm-mFfFjdCbHsDReN0MzPE1hiaHKtPJnzayMec6LiInjzk6YCX41SeF0T1FE7Z6d4Hjy1AkZhLIeebSgX4RrodzwSwZSH0kboTQEfqkrjrk4xw9aM';
NotificationService.sendNotification( NotificationService.sendNotification(
target: token, target: token,
title: 'Hi ,I will go now', title: 'Hi ,I will go now'.tr,
body: 'A passenger is waiting for you.', body: 'A passenger is waiting for you.',
isTopic: false, // Important: this is a token isTopic: false, // Important: this is a token
tone: 'ding',
); );
}, },
child: Text( child: Text(