Інтеграція 1С-Бітрікс з Firebase Cloud Messaging
Інтеграція 1С-Бітрікс з Firebase Cloud Messaging: повний посібник
Firebase Cloud Messaging (FCM) — офіційна інфраструктура Google для push-сповіщень на Android, iOS та в браузері (див. документацію FCM). На відміну від OneSignal, FCM — низькорівневий транспорт без вбудованого UI та сегментації. Інтеграція з 1С-Бітрікс будується повністю на кастомному коді: SDK на фронтенді реєструє токен пристрою, PHP-бекенд відправляє сповіщення через FCM HTTP v1 API. Ми спеціалізуємося на такій інтеграції та гарантуємо стабільну роботу навіть при високих навантаженнях. Оцінимо ваш проект і запропонуємо рішення під ключ.
Як налаштувати FCM HTTP v1 API в 1С-Бітрікс
Google припинив підтримку Legacy HTTP API (ключ server key). Всі нові інтеграції використовують HTTP v1 API з авторизацією через OAuth 2.0 Service Account. Якщо в проекті залишилася стара інтеграція через https://fcm.googleapis.com/fcm/send — вона вже не працює. HTTP v1 endpoint: POST https://fcm.googleapis.com/v1/projects/{project_id}/messages:send. Авторизація — Bearer-токен, отримуваний із Service Account JSON через 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. Токен кешуємо — він діє 1 годину. Перегенерація при кожному запиті — марнотратство.
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 активовано. HTTP v1 API працює в 2 рази швидше за Legacy API завдяки ефективнішій авторизації.
Реєстрація 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'
});
});
Для background-сповіщень потрібен Service Worker /firebase-messaging-sw.js в корені сайту:
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 має обмеження на кількість запитів за секунду. Для масових розсилок використовуйте топіки та додавайте паузи між запитами.
Що вибрати: топіки чи індивідуальні токени?
FCM підтримує відправку за топіками (/topics/promo_electronics) — зручно для масових розсилок без зберігання токенів. Підписка на топік виконується через REST API. Для транзакційних сповіщень (замовлення конкретного користувача) використовуйте лише індивідуальні токени. Індивідуальні токени забезпечують в 5 разів більшу точність доставки для транзакційних сповіщень порівняно з топіками. Топіки кращі для рекламних розсилок, індивідуальні — для персональних оповіщень.
Як обробляти помилки FCM?
Типові помилки та їх вирішення
| Типова помилка | Причина | Рішення |
|---|---|---|
| 404 NOT_FOUND | Токен застарів | Деактивувати токен у базі |
| 403 Forbidden | Невірний Service Account або проект | Перевірити конфігурацію та права доступу |
| 400 InvalidToken | Токен не відповідає формату | Перевірити, що токен отримано від Firebase SDK |
Для масових розсилок можна використовувати топіки, але індивідуальні токени дають більше контролю та персоналізації.
Процес роботи
- Аналітика — вивчаємо архітектуру сайту, визначаємо сценарії push-сповіщень.
- Проектування — проектуємо структуру токенів, інтеграцію з подіями Бітрікс.
- Реалізація — налаштовуємо Service Account, пишемо реєстрацію токенів та відправку.
- Тестування — перевіряємо на всіх платформах (web, Android, iOS), емулюємо сценарії помилок.
- Деплой — розгортаємо на продакшені, налаштовуємо моніторинг.
Що входить у роботу
- Розробка модуля реєстрації FCM-токенів на фронтенді.
- Реалізація PHP-сервісу відправки з підтримкою HTTP v1 API та кешуванням токенів.
- Створення таблиці для зберігання токенів з ORM-описом.
- Інтеграція з системою подій 1С-Бітрікс (створення замовлення, зміна статусу).
- Налаштування Service Worker для background-сповіщень.
- Документація по розгортанню та підтримці.
- Гарантія на роботу інтеграції протягом 30 днів.
Вартість інтеграції починається від 10000 грн при стандартному наборі функцій.
Строки
| Задача | Строк |
|---|---|
| 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 днів.







