تسجيل نتيجة send_fcm.php — مسار الرسائل كان صندوقاً أسود بالكامل

send_fcm.php هي نقطة كل الرسائل والمكالمات بين الراكب والسائق (التطبيقان
يستدعيانها مباشرة)، ولم تكن تحتوي أي error_log إطلاقاً — بخلاف FcmService
التي تطبع [FCM_DEBUG] وتخدم دورة حياة الرحلة فقط.

النتيجة أن فشل الرسائل كان غير قابل للتشخيص: لا سبب، ولا رد Google، ولا
حتى معرفة إن كان الطلب وصل. وقد وعدت المستخدم بقراءة [FCM_DEBUG] لهذا
المسار وهو وعد خاطئ — لا وجود له هنا.

أُضيفت ثلاث نقاط:
- نتيجة الإرسال: category + طرف من التوكن + http + طول التوكن + رد Google
  عند الفشل. طول التوكن مقصود: توكن FCM الحقيقي ~163 محرفاً، والمشفّر في
  جدول tokens 216 — فيُكشف أي blob مشفّر من سطر واحد.
- رفض 403: التطبيقان لا يرسلان x-api-key، فلحظة ضبط FCM_INTERNAL_API_KEY
  تموت كل الرسائل بينهما بصمت. الآن يُسجَّل السبب صريحاً.
- رفض 400 على target فارغ: يعني أن المُرسِل لا يملك توكن الطرف الآخر
  (tokenPassenger أو driverToken لم يصله في حمولة القبول).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Hamza-Ayed
2026-07-27 01:35:01 +03:00
co-authored by Claude Opus 5
parent 77c0b48ec2
commit b84e26fe9a
+18
View File
@@ -6,6 +6,9 @@ header('Content-Type: application/json; charset=utf-8');
$apiKey = $_SERVER['HTTP_X_API_KEY'] ?? ''; $apiKey = $_SERVER['HTTP_X_API_KEY'] ?? '';
$expectedKey = getenv('FCM_INTERNAL_API_KEY'); $expectedKey = getenv('FCM_INTERNAL_API_KEY');
if (!empty($expectedKey) && !hash_equals($expectedKey, $apiKey)) { if (!empty($expectedKey) && !hash_equals($expectedKey, $apiKey)) {
// ‏فشل صامت خطير: التطبيقان لا يرسلان x-api-key إطلاقاً، فلحظة ضبط
// ‏FCM_INTERNAL_API_KEY في البيئة تموت **كل** الرسائل والمكالمات بينهما.
error_log('[SEND_FCM] REJECTED 403 — FCM_INTERNAL_API_KEY set but request sent no x-api-key');
http_response_code(403); http_response_code(403);
echo json_encode(['status' => 'error', 'message' => 'Unauthorized']); echo json_encode(['status' => 'error', 'message' => 'Unauthorized']);
exit; exit;
@@ -49,6 +52,10 @@ $tone = $requestData['tone'] ?? 'default';
$customData = $requestData['data'] ?? []; $customData = $requestData['data'] ?? [];
if (!$target) { if (!$target) {
// ‏يعني أن المُرسِل لا يملك توكن الطرف الآخر — عادةً tokenPassenger أو
// ‏driverToken فارغ في التطبيق لأنه لم يصله في حمولة القبول.
error_log('[SEND_FCM] REJECTED 400 — empty target. category='
. (string)($requestData['data']['category'] ?? '?'));
http_response_code(400); http_response_code(400);
echo json_encode(['status' => 'error', 'message' => 'Missing: target, title, or body.']); echo json_encode(['status' => 'error', 'message' => 'Missing: target, title, or body.']);
exit; exit;
@@ -197,6 +204,17 @@ $result = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch); curl_close($ch);
// ‏هذه النقطة هي مسار كل الرسائل والمكالمات بين الراكب والسائق (التطبيقان
// ‏يستدعيانها مباشرة)، ولم تكن تسجّل شيئاً إطلاقاً — بخلاف FcmService التي
// ‏تطبع [FCM_DEBUG]. فكان فشل الرسائل غير قابل للتشخيص: لا سبب ولا رد Google.
$logCategory = (string)($customData['category'] ?? '');
$logTarget = $isTopic ? "topic:$target" : substr((string)$target, 0, 16) . '…';
error_log(
"[SEND_FCM] category=$logCategory target=$logTarget http=$httpCode"
. " len=" . strlen((string)$target)
. ($httpCode == 200 ? '' : " response=$result")
);
// الرد // الرد
if ($httpCode == 200) { if ($httpCode == 200) {
echo json_encode([ echo json_encode([