Интеграция 1С-Битрикс с Firebase Cloud Messaging
Firebase Cloud Messaging (FCM) — официальная инфраструктура Google для push-уведомлений на Android, iOS и в браузере (см. документацию FCM). В отличие от OneSignal, FCM — низкоуровневый транспорт без встроенного UI и сегментации. Интеграция с 1С-Битрикс строится полностью на кастомном коде: SDK на фронтенде регистрирует токен устройства, PHP-бэкенд отправляет уведомления через FCM HTTP v1 API. Мы специализируемся на такой интеграции и гарантируем стабильную работу даже при высоких нагрузках. Средняя стоимость разработки интеграции FCM с Битрикс — от 200 000 до 400 000 рублей, а экономия на альтернативных сервисах может достигать 40%. Стоимость отправки 10 000 уведомлений — около 0.01 рубля. Оценим ваш проект и предложим решение под ключ.
Как настроить 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 активировано.
Регистрация 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. Для транзакционных уведомлений (заказы конкретного пользователя) используйте только индивидуальные токены. Топики лучше для рекламных рассылок, индивидуальные — для персональных оповещений.
Как обрабатывать ошибки 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 дней.
Сроки
| Задача | Срок |
|---|---|
| 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 дней.







