שילוב 1C-Bitrix עם Firebase Cloud Messaging

הודעות Push הן המפתח למעורבות משתמשים, אך שירותים סטנדרטיים לא תמיד משתלבים בארכיטקטורת 1C-Bitrix. אנחנו מפתחים אינטגרציה של Firebase Cloud Messaging עם קוד מותאם אישית, ומתאימים אותה במלואה לפרויקט שלכם. הצוות שלנו מספק פתרון turnkey—החל מהגדרת token ועד לשליחה דרך FCM HTTP v1 API העדכני—ומבטיח פעילות אמינה עם תמיכה מתמשכת.
השירותים שאנו מציעים
מציג 1 מתוך 1כל 1626 השירותים
שילוב 1C-Bitrix עם Firebase Cloud Messaging
בינוני
~1-2 שבועות

הכישורים שלנו:

שאלות נפוצות

כאשר הפרויקט שלך גדל מעבר לשירותי push חיצוניים, אתה זקוק לאינטגרציה ישירה עם Firebase Cloud Messaging (FCM). אבל ממשק ה-API של FCM בגרסת HTTP v1 דורש הגדרת OAuth 2.0 מותאמת אישית, ניהול טוקנים ו-payloads ספציפיים לפלטפורמה. בניגוד ל-OneSignal, FCM הוא תשתית העברה ברמה נמוכה ללא ממשק משתמש מובנה או segmentation. אנו מתמחים בבניית אינטגרציה זו עבור פרויקטים בעלי עומס גבוה, ומבטיחים אספקה יציבה גם תחת תעבורה כבדה. העלות הסופית נקבעת לאחר ניתוח מעמיק של התשתית והדרישות שלך.

כיצד להגדיר FCM HTTP v1 API ב-1C-Bitrix

גוגל הפסיקה את התמיכה ב-Legacy HTTP API (מפתח שרת). כל האינטגרציות החדשות חייבות להשתמש ב-HTTP v1 API עם הרשאת OAuth 2.0 דרך Service Account. אם הפרויקט שלך עדיין משתמש ב-https://fcm.googleapis.com/fcm/send, הוא יפסיק לפעול. נקודת הקצה של HTTP v1 היא POST https://fcm.googleapis.com/v1/projects/{project_id}/messages:send. ההרשאה מתבצעת עם Bearer token שמתקבל מקובץ JSON של Service Account דרך Google Auth Library.

Service Account והרשאות

ב-Firebase Console → Project Settings → Service Accounts → Generate new private key. הורד את קובץ ה-JSON והנח אותו מחוץ ל-webroot, לדוגמה /var/www/site/storage/firebase/service-account.json. השג את הטוקן דרך JWT. התקן את התלות: composer require google/auth. שמור את הטוקן במטמון — הוא תקף לשעה. יצירתו מחדש בכל בקשה היא בזבוז.

use Google\Auth\Credentials\ServiceAccountCredentials;

class FcmAuthService
{
    private ServiceAccountCredentials $credentials;

    public function __construct(string $serviceAccountPath)
    {
        $this->credentials = new ServiceAccountCredentials(
            'https://www.googleapis.com/auth/firebase.messaging',
            json_decode(file_get_contents($serviceAccountPath), true)
        );
    }

    public function getAccessToken(): string
    {
        $token = $this->credentials->fetchAuthToken();
        return $token['access_token'];
    }

    public function getCachedToken(): string
    {
        $cacheKey = 'fcm_access_token';
        $cached = \Bitrix\Main\Data\Cache::createInstance();
        if ($cached->initCache(3500, $cacheKey, '/fcm/')) {
            return $cached->getVars()['token'];
        }
        $token = $this->getAccessToken();
        $cached->startDataCache();
        $cached->endDataCache(['token' => $token]);
        return $token;
    }
}

עבור FCM HTTP v1 API, נדרש PHP 8.1 ומעלה. ודא שהרחבת curl מופעלת.

רישום טוקן FCM בצד הלקוח

import { initializeApp } from 'firebase/app';
import { getMessaging, getToken, onMessage } from 'firebase/messaging';

const app = initializeApp({
  apiKey: "...",
  authDomain: "project.firebaseapp.com",
  projectId: "project-id",
  messagingSenderId: "123456789",
  appId: "1:123456789:web:abc"
});

const messaging = getMessaging(app);

async function initPush() {
  try {
    const token = await getToken(messaging, { vapidKey: 'YOUR_VAPID_KEY' });
    if (token) {
      await fetch('/local/api/fcm/register', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'X-Bitrix-Csrf-Token': BX.bitrix_sessid()
        },
        body: JSON.stringify({ fcm_token: token, platform: 'web' })
      });
    }
  } catch (err) {
    console.warn('Push permission denied:', err);
  }
}

onMessage(messaging, (payload) => {
  new Notification(payload.notification.title, {
    body: payload.notification.body,
    icon: '/local/templates/main/images/push-icon.png'
  });
});

עבור התראות רקע, אתה זקוק ל-Service Worker בנתיב use Google\Auth\Credentials\ServiceAccountCredentials; class FcmAuthService { private ServiceAccountCredentials $credentials; public function __construct(string $serviceAccountPath) { $this->credentials = new ServiceAccountCredentials( 'https://www.googleapis.com/auth/firebase.messaging', json_decode(file_get_contents($serviceAccountPath), true) ); } public function getAccessToken(): string { $token = $this->credentials->fetchAuthToken(); return $token['access_token']; } public function getCachedToken(): string { $cacheKey = 'fcm_access_token'; $cached = \Bitrix\Main\Data\Cache::createInstance(); if ($cached->initCache(3500, $cacheKey, '/fcm/')) { return $cached->getVars()['token']; } $token = $this->getAccessToken(); $cached->startDataCache(); $cached->endDataCache(['token' => $token]); return $token; } } בשורש האתר:

importScripts('https://www.gstatic.com/firebasejs/10.7.0/firebase-app-compat.js');
importScripts('https://www.gstatic.com/firebasejs/10.7.0/firebase-messaging-compat.js');
firebase.initializeApp({ /* конфиг */ });
const messaging = firebase.messaging();
messaging.onBackgroundMessage((payload) => {
  self.registration.showNotification(payload.notification.title, {
    body: payload.notification.body,
    data: payload.data,
  });
});

אחסון ושליחת התראות

מבנה טבלת מסד נתונים עבור טוקני FCM

class FcmTokenTable extends \Bitrix\Main\ORM\Data\DataManager
{
    public static function getTableName(): string
    {
        return 'local_fcm_tokens';
    }

    public static function getMap(): array
    {
        return [
            new \Bitrix\Main\ORM\Fields\IntegerField('ID', ['primary' => true, 'autocomplete' => true]),
            new \Bitrix\Main\ORM\Fields\IntegerField('USER_ID'),
            new \Bitrix\Main\ORM\Fields\StringField('TOKEN', ['required' => true]),
            new \Bitrix\Main\ORM\Fields\StringField('PLATFORM'), // web, android, ios
            new \Bitrix\Main\ORM\Fields\DatetimeField('CREATED_AT'),
            new \Bitrix\Main\ORM\Fields\DatetimeField('LAST_USED_AT'),
            new \Bitrix\Main\ORM\Fields\StringField('ACTIVE'),
        ];
    }
}

כאשר טוקן מתעדכן (FCM משנה טוקנים בעת התקנה מחדש של האפליקציה), חפש לפי הטוקן הישן והחלף אותו, במקום לשכפל את הרשומה.

שליחת התראה

class FcmService {
    private FcmAuthService $auth;
    private string $projectId;

    public function sendToUser(int $userId, string $title, string $body, array $data = []): void {
        $tokens = FcmTokenTable::getList([
            'filter' => ['USER_ID' => $userId, 'ACTIVE' => 'Y'],
            'select' => ['TOKEN', 'PLATFORM'],
        ])->fetchAll();

        foreach ($tokens as $tokenRow) {
            $this->sendToToken($tokenRow['TOKEN'], $title, $body, $data, $tokenRow['PLATFORM']);
        }
    }

    private function sendToToken(string $token, string $title, string $body, array $data, string $platform): void {
        $message = [
            'token' => $token,
            'notification' => ['title' => $title, 'body' => $body],
            'data' => array_map('strval', $data),
        ];

        if ($platform === 'android') {
            $message['android'] = [
                'priority' => 'high',
                'notification' => ['channel_id' => 'orders', 'icon' => 'ic_notification'],
            ];
        } elseif ($platform === 'ios') {
            $message['apns'] = [
                'headers' => ['apns-priority' => '10'],
                'payload' => ['aps' => ['sound' => 'default', 'badge' => 1]],
            ];
        }

        $accessToken = $this->auth->getCachedToken();
        $projectId = $this->projectId;
        $url = "https://fcm.googleapis.com/v1/projects/{$projectId}/messages:send";

        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => json_encode(['message' => $message]),
            CURLOPT_HTTPHEADER => [
                'Content-Type: application/json',
                "Authorization: Bearer {$accessToken}",
            ],
        ]);

        $response = json_decode(curl_exec($ch), true);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($httpCode === 404 || ($response['error']['code'] ?? 0) === 404) {
            FcmTokenTable::updateByToken($token, ['ACTIVE' => 'N']);
        }
    }
}

בעיות נפוצות במהלך אינטגרציית FCM

השגיאות הבאות נתקלות לעיתים קרובות במהלך ההתקנה:

  • Service Account לא תקין: קובץ ה-JSON פגום או בעל הרשאות שגויות. ודא שהקובץ קריא על ידי שרת האינטרנט ומכיל את ה-project_id הנכון.
  • טוקן מיושן: אם הלקוח אינו מרענן את הטוקן, ההתראות מפסיקות להגיע. יישם רענון טוקן בצד הלקוח וטיפול בשגיאות 404 בצד השרת.
  • חריגה ממכסה: ל-FCM יש מגבלה על בקשות בשנייה. עבור שליחות המוניות, השתמש בנושאים (topics) והוסף הפסקות בין הבקשות.

נושאים (Topics) לעומת טוקנים אישיים: מה לבחור?

FCM תומך בשליחה לנושאים (import { initializeApp } from 'firebase/app'; import { getMessaging, getToken, onMessage } from 'firebase/messaging'; const app = initializeApp({ apiKey: "...", authDomain: "project.firebaseapp.com", projectId: "project-id", messagingSenderId: "123456789", appId: "1:123456789:web:abc" }); const messaging = getMessaging(app); async function initPush() { try { const token = await getToken(messaging, { vapidKey: 'YOUR_VAPID_KEY' }); if (token) { await fetch('/local/api/fcm/register', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Bitrix-Csrf-Token': BX.bitrix_sessid() }, body: JSON.stringify({ fcm_token: token, platform: 'web' }) }); } } catch (err) { console.warn('Push permission denied:', err); } } onMessage(messaging, (payload) => { new Notification(payload.notification.title, { body: payload.notification.body, icon: '/local/templates/main/images/push-icon.png' }); }); ) וזה נוח לקמפיינים המוניים ללא אחסון טוקנים. ההרשמה לנושא מתבצעת דרך REST API. עבור התראות טרנזקציוניות (לדוגמה, הזמנה של משתמש ספציפי), השתמש רק בטוקנים אישיים. נושאים מתאימים יותר למבצעים שיווקיים, בעוד שטוקנים אישיים מיועדים להתראות מותאמות אישית.

כיצד לטפל בשגיאות FCM?

שגיאה נפוצה סיבה פתרון
404 NOT_FOUND הטוקן מיושן השבת את הטוקן במסד הנתונים
403 Forbidden Service Account או פרויקט לא תקין בדוק את התצורה וההרשאות
400 InvalidToken הטוקן אינו תואם לפורמט ודא שהטוקן התקבל מ-Firebase SDK

עבור שליחות המוניות, ניתן להשתמש בנושאים, אך טוקנים אישיים מציעים יותר שליטה והתאמה אישית.

תהליך העבודה

  1. ניתוח — חקר ארכיטקטורת האתר, הגדרת תרחישי התראות push.
  2. עיצוב — עיצוב מבנה אחסון הטוקנים, אינטגרציה עם אירועי Bitrix.
  3. יישום — הגדרת Service Account, כתיבת לוגיקת רישום ושליחת טוקנים.
  4. בדיקות — אימות בכל הפלטפורמות (web, Android, iOS), הדמיית תרחישי שגיאה.
  5. פריסה — פריסה לסביבת הייצור, הגדרת ניטור.

מה כלול בעבודה

  • פיתוח מודול צד לקוח לרישום טוקני FCM.
  • יישום שירות שליחה ב-PHP התומך ב-HTTP v1 API עם מטמון טוקנים.
  • יצירת טבלת אחסון טוקנים עם מיפוי ORM.
  • אינטגרציה עם מערכת האירועים של 1C-Bitrix (יצירת הזמנה, שינוי סטטוס).
  • הגדרת Service Worker להתראות רקע.
  • תיעוד לפריסה ותחזוקה.
  • אחריות ל-30 יום על האינטגרציה.

הערכות זמן

משימה משך זמן
Service Account, לקוח FCM HTTP v1, מטמון טוקנים 2–3 ימים
רישום טוקנים (web + android/ios) 3–4 ימים
שליחה מונעת אירועים (אירועי הזמנה) + טיפול בשגיאות 2–3 ימים
Service Worker, התראות foreground/background 2–3 ימים
ניהול הרשמות מפרופיל המשתמש, נושאים 3–5 ימים
חבילה מלאה 3–4 שבועות

לוחות הזמנים הם משוערים ותלויים במורכבות הפרויקט. מועדים מדויקים נקבעים לאחר ביקורת.

קבל ייעוץ בנושא יישום FCM בפרויקט שלך. הזמן אינטגרציה סוהר עם אחריות ל-30 יום.