25-10-5/1

This commit is contained in:
Hamza-Ayed
2025-10-05 14:57:32 +03:00
parent 95fb065bdb
commit 1cc66029a3
28 changed files with 1347 additions and 666 deletions

View File

@@ -85,9 +85,9 @@ class FirebaseMessagesController extends GetxController {
if (message.data.isNotEmpty && message.notification != null) {
fireBaseTitles(message);
}
if (message.data.isNotEmpty && message.notification != null) {
fireBaseTitles(message);
}
// if (message.data.isNotEmpty && message.notification != null) {
// fireBaseTitles(message);
// }
});
FirebaseMessaging.onBackgroundMessage((RemoteMessage message) async {});
@@ -387,33 +387,12 @@ class FirebaseMessagesController extends GetxController {
// }));
// }
Future<dynamic> passengerDialog(String message) {
return Get.defaultDialog(
barrierDismissible: false,
title: 'message From passenger'.tr,
titleStyle: AppStyle.title,
middleTextStyle: AppStyle.title,
middleText: message.tr,
confirm: MyElevatedButton(
title: 'Ok'.tr,
onPressed: () {
// FirebaseMessagesController().sendNotificationToPassengerToken(
// 'Hi ,I will go now'.tr,
// 'I will go now'.tr,
// Get.find<MapPassengerController>().driverToken, []);
// Get.find<MapPassengerController>()
// .startTimerDriverWaitPassenger5Minute();
Get.back();
}));
}
late String serviceAccountKeyJson;
@override
Future<void> onInit() async {
super.onInit();
try {
getToken();
// getToken();
var encryptedKey = Env.privateKeyFCM;
// Log.print('encryptedKey: ${encryptedKey}');
serviceAccountKeyJson =
@@ -425,67 +404,84 @@ class FirebaseMessagesController extends GetxController {
}
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);
// توكني الحالي (لا أرسل لنفسي)
final String myToken = box.read(BoxName.tokenFCM) ?? '';
// اقرأ قائمة كل التوكنات
final List<String> all =
List<String>.from(box.read(BoxName.tokens) ?? const []);
// 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++) {
if (serviceAccountKeyJson.isEmpty) {
print("🔴 Error: Service Account Key is empty");
return;
}
// Initialize AccessTokenManager
final accessTokenManager = AccessTokenManager(serviceAccountKeyJson);
// استبعد توكنك واحذف الفارغ
final targets = all.where((t) => t.isNotEmpty && t != myToken).toList();
// Obtain an OAuth 2.0 access token
final accessToken = await accessTokenManager.getAccessToken();
// Log.print('accessToken: ${accessToken}');
if (serviceAccountKeyJson.isEmpty) {
print("🔴 Error: Service Account Key is empty");
return;
}
final accessTokenManager = AccessTokenManager(serviceAccountKeyJson);
final accessToken = await accessTokenManager.getAccessToken();
// 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',
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',
},
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,
},
},
},
'apns': {
'headers': {
'apns-priority': '10',
// لو iOS: حدد نوع الدفع
'apns-push-type': 'alert',
},
}),
)
.whenComplete(() {})
.catchError((e) {});
'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}');
}
}
@@ -523,7 +519,7 @@ class FirebaseMessagesController extends GetxController {
'passengerList': jsonEncode(map),
},
'android': {
'priority': 'high', // Set priority to high
'priority': 'HIGH ', // Set priority to high
'notification': {
'sound': tone,
},
@@ -605,7 +601,7 @@ class FirebaseMessagesController extends GetxController {
'passengerList': jsonEncode(map),
},
'android': {
'priority': 'high', // Set priority to high
'priority': 'HIGH ', // Set priority to high
'notification': {
'sound': tone,
},
@@ -692,7 +688,7 @@ class FirebaseMessagesController extends GetxController {
'DriverList': jsonEncode(data),
},
'android': {
'priority': 'high', // Set priority to high
'priority': 'HIGH ', // Set priority to high
'notification': {
'sound': tone,
},