Update: 2026-06-12 01:23:54
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import '../env/env.dart';
|
||||
|
||||
class AppLink {
|
||||
import '../main.dart';
|
||||
import 'box_name.dart';class AppLink {
|
||||
static String seferPaymentServer =
|
||||
'https://walletintaleq.intaleq.xyz/v1/main';
|
||||
static final String tripzPaymentServer0 = seferPaymentServer;
|
||||
@@ -11,15 +11,64 @@ class AppLink {
|
||||
// static final String endPoint = box.read(BoxName.serverChosen);
|
||||
// static final String server = Env.seferCairoServer;
|
||||
|
||||
static final String server = 'https://api.intaleq.xyz/siro_v3';
|
||||
static final String endPoint = 'https://api.intaleq.xyz/siro_v3';
|
||||
static final String syria = 'https://syria.intaleq.xyz/siro';
|
||||
static String paymentServer = 'https://walletintaleq.intaleq.xyz/v1/main';
|
||||
static String locationServer = 'https://location.intaleq.xyz/siro/ride/location';
|
||||
static String locationServerSide = 'https://location.intaleq.xyz/siro/ride/location';
|
||||
static String mapSaasRoute = 'https://map-saas.intaleqapp.com/api/maps/route';
|
||||
static String mapSaasPlaces = 'https://map-saas.intaleqapp.com/api/geocoding/places';
|
||||
static const String routeApiBaseUrl = "https://routesjo.intaleq.xyz/route/v1/driving";
|
||||
static String get currentCountry => box.read('countryCode') ?? 'Jordan';
|
||||
|
||||
static String get server {
|
||||
switch (currentCountry) {
|
||||
case 'Syria': return 'https://api-syria.siromove.com/siro_v3';
|
||||
case 'Egypt': return 'https://api-egypt.siromove.com/siro_v3';
|
||||
case 'Jordan': return 'https://api-jordan.siromove.com/siro_v3';
|
||||
default: return 'https://api.siromove.com/siro_v3';
|
||||
}
|
||||
}
|
||||
static String get endPoint => server;
|
||||
static String get syria => 'https://api-syria.siromove.com/siro';
|
||||
|
||||
static String get paymentServer {
|
||||
switch (currentCountry) {
|
||||
case 'Syria': return 'https://wallet-syria.siromove.com/v1/main';
|
||||
case 'Egypt': return 'https://wallet-egypt.siromove.com/v1/main';
|
||||
case 'Jordan': return 'https://wallet-jordan.siromove.com/v1/main';
|
||||
default: return 'https://wallet.siromove.com/v1/main';
|
||||
}
|
||||
}
|
||||
|
||||
static String get locationServer {
|
||||
switch (currentCountry) {
|
||||
case 'Syria': return 'https://location-syria.siromove.com/siro/ride/location';
|
||||
case 'Egypt': return 'https://location-egypt.siromove.com/siro/ride/location';
|
||||
case 'Jordan': return 'https://location-jordan.siromove.com/siro/ride/location';
|
||||
default: return 'https://location.siromove.com/siro/ride/location';
|
||||
}
|
||||
}
|
||||
static String get locationServerSide => locationServer;
|
||||
|
||||
static String get mapSaasRoute {
|
||||
switch (currentCountry) {
|
||||
case 'Syria': return 'https://map-syria.siromove.com/api/maps/route';
|
||||
case 'Egypt': return 'https://map-egypt.siromove.com/api/maps/route';
|
||||
case 'Jordan': return 'https://map-jordan.siromove.com/api/maps/route';
|
||||
default: return 'https://map-saas.intaleqapp.com/api/maps/route';
|
||||
}
|
||||
}
|
||||
|
||||
static String get mapSaasPlaces {
|
||||
switch (currentCountry) {
|
||||
case 'Syria': return 'https://map-syria.siromove.com/api/geocoding/places';
|
||||
case 'Egypt': return 'https://map-egypt.siromove.com/api/geocoding/places';
|
||||
case 'Jordan': return 'https://map-jordan.siromove.com/api/geocoding/places';
|
||||
default: return 'https://map-saas.intaleqapp.com/api/geocoding/places';
|
||||
}
|
||||
}
|
||||
|
||||
static String get routeApiBaseUrl {
|
||||
switch (currentCountry) {
|
||||
case 'Syria': return 'https://routes-syria.siromove.com/route/v1/driving';
|
||||
case 'Egypt': return 'https://routes-egypt.siromove.com/route/v1/driving';
|
||||
case 'Jordan': return 'https://routes-jordan.siromove.com/route/v1/driving';
|
||||
default: return 'https://routes.siromove.com/route/v1/driving';
|
||||
}
|
||||
}
|
||||
static String loginJwtDriver =
|
||||
"https://api.intaleq.xyz/siro/loginAdmin.php";
|
||||
//=============================
|
||||
|
||||
@@ -20,6 +20,7 @@ import '../../views/widgets/elevated_btn.dart';
|
||||
import '../functions/encrypt_decrypt.dart';
|
||||
import '../notification_controller.dart';
|
||||
import 'local_notification.dart';
|
||||
import 'notification_service.dart';
|
||||
import 'token_access.dart';
|
||||
|
||||
class FirebaseMessagesController extends GetxController {
|
||||
@@ -364,66 +365,6 @@ class FirebaseMessagesController extends GetxController {
|
||||
// ));
|
||||
// }
|
||||
|
||||
void sendNotificationAll(String title, body) 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++) {
|
||||
String serviceAccountKeyJson = '''{
|
||||
"type": "service_account",
|
||||
"project_id": "ride-b1bd8",
|
||||
"private_key_id": "75e817c0b902db2ef35edf2c2bd159dec1f13249",
|
||||
"private_key": "-----BEGIN PRIVATE KEY-----\\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQD0zH9TQGDQHUv3\\na3/JAD1UKPwAp3wNKT0a6fxiIzjI3JxQWI30QvZCcfl6CdMhIcydX1ncSaYTcEeC\\n/AdPVCPkqyJx1YIGGg6P/mRzCWeaN8fsp6z250m5vcObDCZc3dbJEkepbep+6FPY\\n21m3KO+AHh1glgsTGZOTm5xiU8NGXpdk2QEh8wpiIIlR/HuKwVw9g8urNe3Sno+U\\nDm3z37iFqvZdmpqO8aWTJu6beb3hsREK9XK2I9JqC2JUwiGQRo3idOvPP6hkqrWx\\nKSX96vglQFYfakvJdDp2ZATOlpBYPMtS/IWhJ985u58TSS+Kl8qpnpaZBSxgJirf\\nhWzhnKLfAgMBAAECggEAJP785SePGhS7ZN6ltspm+l+hSjYFrPWFCxq+rlQ1YkHZ\\nC9l+RqKSFhOkiPmQI2s4wbXl3kFxLHHlFNoi/q2wKQBmGb8TQfnRJpjjNHGA61Ev\\n0Ue7/6qPvVb9B2MsLw/FxKiTFPuMG3bgKR9pbSFuJLYoaW7zqITOhVnYphGTqwAY\\nBVVcvISSLvELDmH9VZcv/9DVqVlqbbESHWh1Z4W6XGPoEqeDH/upNTyQQ/46Msgm\\nTGE6VqLHpWuSf6SqHp+r0Y0lI3vIPM1vz5FAJDJbOE/enHa0fSup0OHSMxl0HVMn\\nnO1yrGF3vsIPOej5HKr5d71bEIckzk73/yjNC1/mDQKBgQD7RtUvc9omsSsFMJ6e\\nBASAn6Dktx/QY/XNJjFzHQj69cywLDe5t5AL2gUi3phQ2oqB5XJdwnd5bTIEPEPZ\\nDOuOai2802p6FJk6kjmZAMVGx5JtXBH+vs6jrmQQSMiKbjwN1TT6xIWakvLOonUi\\nX6ZvjYYjU/E0YJU3jSiXWEr76wKBgQD5Zn4SouJ6BCDZMbausJVMBkk3qxsYooip\\np89WakC6e7AZinpkRcqjGGV9GOvc8crJs6fyXAA9ORepGP47Mc0ZrDssOkstznsM\\npr8R0S6MKwEZaT9ixOHdOcLZ47ps+JzA2Wr4KN2OvFHksUkB/46ATD1j9WZVgB8M\\namsYp/Y73QKBgHOo+PvsoZ9psVmkNX6abtAdqdtdB0HOoRea2uwXk0ig12TIFaZg\\nfedWpUKVnxqoXVTJHklV99RmlL0qWDiSH+LfsMnXro0e6iDxqZ1po2Se/CFmXcoa\\nXdctsFVmixhdATuExewfhTfPKABA+xWlXWC/jdy5CK+JPWXijaqMM4edAoGAE5Bj\\nsWiPpYyvWvpYX0nA3G7dzX0hqgQN/mkIjbnWDArp3IcNZNJIvBSM2Yxb7EAXbU0n\\njo6DAkp5Pa2VO+WDNlFZbvW/sf8xjeOCt44WPa6d7nVgIIpbQXRngZoopKW3/jTP\\n/FmQT8McFXmGxZ5belsAsdetSGW9icbLUerTGQ0CgYEAmf/G8Ag3XxmqTXvvHuv2\\n14OP7WnrVqkEMnydrftEwn4peXd/Lz+/GYX5Zc4ZoNgbN8IvZ5z0+OmRsallsbiW\\nBw0/tc68CjzxXOvReWxDluUopqWVGj5tlGqE5xUDku9SWJSxbkiQ3rqutzBdPXpr\\noqHwPyDrmK/Zgqn+uiIm4Ck=\\n-----END PRIVATE KEY-----\\n",
|
||||
"client_email": "firebase-adminsdk-o2wqi@ride-b1bd8.iam.gserviceaccount.com",
|
||||
"client_id": "111210077025005706623",
|
||||
"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-o2wqi%40ride-b1bd8.iam.gserviceaccount.com",
|
||||
"universe_domain": "googleapis.com"
|
||||
}
|
||||
'''; // As defined above
|
||||
|
||||
// Initialize AccessTokenManager
|
||||
final accessTokenManager = AccessTokenManager(serviceAccountKeyJson);
|
||||
|
||||
// Obtain an OAuth 2.0 access token
|
||||
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',
|
||||
},
|
||||
body: jsonEncode({
|
||||
'notification': <String, dynamic>{
|
||||
'title': title,
|
||||
'body': body,
|
||||
'sound': 'ding.wav'
|
||||
},
|
||||
'priority': 'high',
|
||||
'data': <String, dynamic>{
|
||||
'click_action': 'FLUTTER_NOTIFICATION_CLICK',
|
||||
'id': '1',
|
||||
'status': 'done'
|
||||
},
|
||||
'to': tokens[i],
|
||||
}))
|
||||
.whenComplete(() {})
|
||||
.catchError((e) {});
|
||||
}
|
||||
}
|
||||
|
||||
// for (var i = 0; i < tokens.length; i++) {
|
||||
// http
|
||||
// .post(Uri.parse('https://fcm.googleapis.com/fcm/send'),
|
||||
@@ -452,66 +393,18 @@ class FirebaseMessagesController extends GetxController {
|
||||
// }
|
||||
//android/app/src/main/res/raw/iphone_ringtone.wav
|
||||
|
||||
late String serviceAccountKeyJson;
|
||||
void sendNotificationAll(String title, body) async {
|
||||
// Deprecated: Admin panel notifications are sent via NotificationService.
|
||||
}
|
||||
|
||||
void sendNotificationToAnyWithoutData(
|
||||
String title, String body, String token, String tone) async {
|
||||
try {
|
||||
var encryptedKey = Env.privateKeyFCM;
|
||||
// Log.print('encryptedKey: ${encryptedKey}');
|
||||
serviceAccountKeyJson =
|
||||
EncryptionHelper.instance.decryptData(encryptedKey);
|
||||
// As defined above
|
||||
|
||||
// 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/siro-d48a7/messages:send'),
|
||||
headers: <String, String>{
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': 'Bearer $accessToken',
|
||||
},
|
||||
body: jsonEncode({
|
||||
'message': {
|
||||
'token': token,
|
||||
'notification': {
|
||||
'title': title,
|
||||
'body': body,
|
||||
},
|
||||
'android': {
|
||||
'notification': {
|
||||
'sound': tone,
|
||||
},
|
||||
},
|
||||
'apns': {
|
||||
'payload': {
|
||||
'aps': {
|
||||
'sound': tone,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
SnackBar(content: Text('${response.statusCode}'));
|
||||
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}');
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error sending notification: $e');
|
||||
}
|
||||
await NotificationService.sendNotification(
|
||||
target: token,
|
||||
title: title,
|
||||
body: body,
|
||||
category: 'fromAdmin',
|
||||
tone: tone,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import 'dart:convert';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
import '../../print.dart';
|
||||
import '../../constant/links.dart';
|
||||
|
||||
class NotificationService {
|
||||
// تأكد من أن هذا هو الرابط الصحيح لملف الإرسال
|
||||
static const String _serverUrl =
|
||||
'https://syria.intaleq.xyz/siro/fcm/send_fcm.php';
|
||||
static String get _serverUrl => '${AppLink.server.replaceAll('_v3', '')}/ride/firebase/send_fcm.php';
|
||||
|
||||
static Future<void> sendNotification({
|
||||
required String target,
|
||||
|
||||
@@ -1,53 +1,51 @@
|
||||
import 'dart:convert';
|
||||
import 'package:googleapis_auth/auth_io.dart';
|
||||
// import 'dart:convert';
|
||||
|
||||
import '../../print.dart';
|
||||
// import '../../print.dart';
|
||||
|
||||
class AccessTokenManager {
|
||||
static final AccessTokenManager _instance = AccessTokenManager._internal();
|
||||
late final String serviceAccountJsonKey;
|
||||
AccessToken? _accessToken;
|
||||
DateTime? _expiryDate;
|
||||
// class AccessTokenManager {
|
||||
// static final AccessTokenManager _instance = AccessTokenManager._internal();
|
||||
// late final String serviceAccountJsonKey;
|
||||
// DateTime? _expiryDate;
|
||||
|
||||
AccessTokenManager._internal();
|
||||
// AccessTokenManager._internal();
|
||||
|
||||
factory AccessTokenManager(String jsonKey) {
|
||||
if (_instance._isServiceAccountKeyInitialized()) {
|
||||
// Prevent re-initialization
|
||||
return _instance;
|
||||
}
|
||||
_instance.serviceAccountJsonKey = jsonKey;
|
||||
return _instance;
|
||||
}
|
||||
// factory AccessTokenManager(String jsonKey) {
|
||||
// if (_instance._isServiceAccountKeyInitialized()) {
|
||||
// // Prevent re-initialization
|
||||
// return _instance;
|
||||
// }
|
||||
// _instance.serviceAccountJsonKey = jsonKey;
|
||||
// return _instance;
|
||||
// }
|
||||
|
||||
bool _isServiceAccountKeyInitialized() {
|
||||
try {
|
||||
serviceAccountJsonKey; // Access to check if initialized
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// bool _isServiceAccountKeyInitialized() {
|
||||
// try {
|
||||
// serviceAccountJsonKey; // Access to check if initialized
|
||||
// return true;
|
||||
// } catch (e) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
|
||||
Future<String> getAccessToken() async {
|
||||
if (_accessToken != null && DateTime.now().isBefore(_expiryDate!)) {
|
||||
return _accessToken!.data;
|
||||
}
|
||||
try {
|
||||
final serviceAccountCredentials = ServiceAccountCredentials.fromJson(
|
||||
json.decode(serviceAccountJsonKey));
|
||||
final client = await clientViaServiceAccount(
|
||||
serviceAccountCredentials,
|
||||
['https://www.googleapis.com/auth/firebase.messaging'],
|
||||
);
|
||||
// Future<String> getAccessToken() async {
|
||||
// if (_accessToken != null && DateTime.now().isBefore(_expiryDate!)) {
|
||||
// return _accessToken!.data;
|
||||
// }
|
||||
// try {
|
||||
// final serviceAccountCredentials = ServiceAccountCredentials.fromJson(
|
||||
// json.decode(serviceAccountJsonKey));
|
||||
// final client = await clientViaServiceAccount(
|
||||
// serviceAccountCredentials,
|
||||
// ['https://www.googleapis.com/auth/firebase.messaging'],
|
||||
// );
|
||||
|
||||
_accessToken = client.credentials.accessToken;
|
||||
_expiryDate = client.credentials.accessToken.expiry;
|
||||
client.close();
|
||||
Log.print('_accessToken!.data: ${_accessToken!.data}');
|
||||
return _accessToken!.data;
|
||||
} catch (e) {
|
||||
throw Exception('Failed to obtain access token');
|
||||
}
|
||||
}
|
||||
}
|
||||
// _accessToken = client.credentials.accessToken;
|
||||
// _expiryDate = client.credentials.accessToken.expiry;
|
||||
// client.close();
|
||||
// Log.print('_accessToken!.data: ${_accessToken!.data}');
|
||||
// return _accessToken!.data;
|
||||
// } catch (e) {
|
||||
// throw Exception('Failed to obtain access token');
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
@@ -29,12 +29,12 @@ class WalletController extends GetxController {
|
||||
'driverID': driverID.toString(),
|
||||
});
|
||||
if (res != 'failure') {
|
||||
FirebaseMessagesController().sendNotificationToAnyWithoutData(
|
||||
"لديك هدية من سفَر".tr,
|
||||
'لقد حصلت على هدية من سفر بقيمة $amount ',
|
||||
token, // Access token correctly
|
||||
'ding.wav',
|
||||
);
|
||||
// FirebaseMessagesController().sendNotificationToAnyWithoutData(
|
||||
// "لديك هدية من سفَر".tr,
|
||||
// 'لقد حصلت على هدية من سفر بقيمة $amount ',
|
||||
// token, // Access token correctly
|
||||
// 'ding.wav',
|
||||
// );
|
||||
Get.snackbar('success', 'addPaymentToDriver',
|
||||
backgroundColor: AppColor.greenColor);
|
||||
} else {
|
||||
|
||||
@@ -249,7 +249,8 @@ class CaptainDetailsPage extends StatelessWidget {
|
||||
borderRadius: BorderRadius.circular(12)),
|
||||
),
|
||||
onPressed: () {
|
||||
Get.to(() => DriverScorecardPage(driverId: data['id'].toString()));
|
||||
Get.to(
|
||||
() => DriverScorecardPage(driverId: data['id'].toString()));
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -380,11 +381,11 @@ class CaptainDetailsPage extends StatelessWidget {
|
||||
// Check if key is valid (might be recreated)
|
||||
if (controller.formCaptainPrizeKey.currentState?.validate() ??
|
||||
true) {
|
||||
FirebaseMessagesController().sendNotificationToAnyWithoutData(
|
||||
controller.titleNotify.text,
|
||||
controller.bodyNotify.text,
|
||||
data['passengerToken'] ?? '', // Safety check
|
||||
'order.wav');
|
||||
// FirebaseMessagesController().sendNotificationToAnyWithoutData(
|
||||
// controller.titleNotify.text,
|
||||
// controller.bodyNotify.text,
|
||||
// data['passengerToken'] ?? '', // Safety check
|
||||
// 'order.wav');
|
||||
Get.back();
|
||||
Get.snackbar("Success", "Notification Sent",
|
||||
backgroundColor: Colors.green.withOpacity(0.2));
|
||||
|
||||
@@ -393,11 +393,11 @@ class PassengerDetailsPage extends StatelessWidget {
|
||||
onPressed: () {
|
||||
// Validate form safely
|
||||
if (controller.formPrizeKey.currentState?.validate() ?? false) {
|
||||
FirebaseMessagesController().sendNotificationToAnyWithoutData(
|
||||
controller.titleNotify.text,
|
||||
controller.bodyNotify.text,
|
||||
data['passengerToken'],
|
||||
'order.wav');
|
||||
// FirebaseMessagesController().sendNotificationToAnyWithoutData(
|
||||
// controller.titleNotify.text,
|
||||
// controller.bodyNotify.text,
|
||||
// data['passengerToken'],
|
||||
// 'order.wav');
|
||||
Get.back();
|
||||
Get.snackbar('Success', 'Notification sent successfully!',
|
||||
backgroundColor: Colors.green.withOpacity(0.2));
|
||||
|
||||
Reference in New Issue
Block a user