
📱 Отправка push-уведомлений через Google FCM и PHP: руководство 2026
Приложение установили, а через день о нем забыли. Возврат пользователя, одна из самых острых проблем мобильной разработки: без внешнего триггера человек просто не вспомнит открыть приложение снова.
Push-уведомления решают эту задачу напрямую. Один короткий сигнал на экране блокировки, и пользователь возвращается к вашему контенту или действию. С июня 2024 года Google полностью отключил legacy-версию FCM API вместе с аутентификацией по серверному ключу. Работает только HTTP v1 API с OAuth 2.0.
Ниже, пошаговое руководство по настройке Firebase Cloud Messaging и отправке кросс-платформенных push-уведомлений через PHP: от создания проекта до приема уведомления на Android и iOS.
Что такое FCM и почему старый API отключен
💡 Быстрый обзор:
- Создаете проект Firebase, получаете JSON-ключ
- Настраиваете клиентский SDK, получаете FCM-токен
- Устанавливаете
kreait/firebase-phpчерез Composer - Отправляете push-уведомление в топик одним вызовом
- Принимаете уведомление на устройстве за 1-3 секунды
Firebase Cloud Messaging (FCM), это кроссплатформенный сервис Google для отправки уведомлений на Android, iOS и веб. Он бесплатен, не имеет жестких квот на количество сообщений и работает через единый серверный API.
Предшественник FCM, Google Cloud Messaging (GCM), использовал схему с регистрационными ID устройств и серверным ключом. Разработчик хранил токены у себя в базе и гонял уведомления в цикле. FCM добавил топики (тематические каналы): устройство подписывается на /topics/news, и сервер шлет сообщение сразу всей группе без перебора токенов.
В июне 2023 года Google объявил об устаревании legacy HTTP API, а с середины 2024 года он полностью отключен. Старый эндпоинт https://android.googleapis.com/gcm/send больше не принимает запросы. Вместо серверного ключа теперь нужен OAuth 2.0-токен, получаемый из JSON-файла сервисного аккаунта Firebase. Подробности миграции: в официальной документации FCM.
Обратите внимание: Instance ID API (iid.googleapis.com) для управления подписками на топики также выведен из эксплуатации. Современный способ, подписка на клиенте через Firebase SDK или управление через Firebase Admin SDK на сервере.
Шаг 1: Создание проекта в Firebase Console
Зайдите в Firebase Console под своей учетной записью Google. Нажмите «Создать проект», задайте имя и дождитесь инициализации.

После создания проекта перейдите в Project Settings → Service Accounts. Нажмите «Generate new private key», скачается JSON-файл с учетными данными. Сохраните его в защищенную папку сервера (вне document root): именно через него PHP-клиент будет получать OAuth 2.0-токен для HTTP v1 API.
Там же, в Project Settings → Cloud Messaging, добавьте iOS-сертификаты APNs, если планируете отправлять уведомления на устройства Apple. Без этого шага push на iOS ходить не будет.
Шаг 2: Настройка клиентского SDK
Чтобы сервер знал, куда отправлять уведомление, клиентское приложение должно получить FCM-токен и передать его на ваш сервер. Настройка для обеих платформ, в документации Firebase, здесь, опорные точки.
iOS
Определите URL-адрес регистрации устройства, эндпоинт вашего PHP-скрипта, который принимает токен:
Минимальная интеграция Firebase SDK в iOS-приложение:

При каждом запуске приложение вызывает Messaging.messaging().token(), получает актуальный FCM-токен и отправляет его на ваш регистрационный URL. Токен может измениться при переустановке приложения, не сохраняйте его навсегда, обновляйте при каждом запуске.
Android
Логика та же: задаете URL серверного эндпоинта для регистрации токена:

Интеграция Firebase SDK на стороне Android:

На Android токен также обновляется при переустановке приложения и очистке данных, учитывайте это при проектировании серверной таблицы устройств.
Шаг 3: Установка PHP-библиотеки и аутентификация
Для работы с HTTP v1 API через PHP нужна библиотека, берущая на себя получение OAuth 2.0-токена из JSON-файла сервисного аккаунта. Самый зрелый вариант на середину 2026 года, kreait/firebase-php. Установка через Composer:
1 composer require kreait/firebase-php
Файл send_push.php, инициализация клиента:
1 <?php 2 require_once __DIR__ . '/vendor/autoload.php'; 3 4 use Kreait\Firebase\Factory; 5 use Kreait\Firebase\Messaging\CloudMessage; 6 use Kreait\Firebase\Messaging\Notification; 7 8 $factory = (new Factory) 9 ->withServiceAccount('/путь/к/serviceAccountKey.json'); 10 11 $messaging = $factory->createMessaging();
Проверьте, что путь к JSON-ключу абсолютный и файл читается процессом PHP. Никогда не кладите JSON-ключ в публичную папку сайта, при прямом доступе через браузер злоумышленник получит полный доступ к вашему проекту Firebase.
Шаг 4: Отправка уведомления через HTTP v1 API
Теперь сам механизм отправки. Код ниже принимает заголовок и текст уведомления из формы, формирует payload и отправляет его в заданный топик:
1 <?php 2 require_once __DIR__ . '/vendor/autoload.php'; 3 4 use Kreait\Firebase\Factory; 5 use Kreait\Firebase\Messaging\CloudMessage; 6 use Kreait\Firebase\Messaging\Notification; 7 8 $factory = (new Factory) 9 ->withServiceAccount('/путь/к/serviceAccountKey.json'); 10 11 $messaging = $factory->createMessaging(); 12 13 $topic = 'my-app'; 14 15 $notification = Notification::create( 16 $_POST['title'] ?? 'Новое уведомление', 17 $_POST['summary'] ?? '' 18 ); 19 20 $message = CloudMessage::withTarget('topic', $topic) 21 ->withNotification($notification) 22 ->withData([ 23 'action' => 'models', 24 'model_id' => '2701', 25 ]) 26 ->withHighestPossiblePriority(); 27 28 try { 29 $result = $messaging->send($message); 30 echo "Уведомление отправлено. ID: " . json_encode($result); 31 } catch (\Kreait\Firebase\Exception\MessagingException $e) { 32 echo "Ошибка отправки: " . $e->getMessage(); 33 }
Разбор ключевых моментов:
CloudMessage::withTarget('topic', $topic), отправка в топик; для отправки конкретному устройству замените наwithTarget('token', 'DEVICE_TOKEN').->withData([...]), кастомные данные для deep linking: при тапе по уведомлению приложение открывает конкретный экран (в примере, страницу модели).->withHighestPossiblePriority(), приоритет high, уведомление доставляется немедленно; для тихих фоновых событий используйтеnormal.MessagingExceptionловит ошибки валидации, аутентификации и сетевые сбои, всегда оборачивайте отправку в try/catch.
Этот код полностью заменяет устаревшую связку curl + Authorization:key=SERVER_KEY + эндпоинт gcm/send, которая не работает с 2024 года.
Форма для ручной отправки
Для быстрого теста, простой HTML-интерфейс:
1 <form method="POST" action="send_push.php"> 2 <input type="text" name="title" placeholder="Заголовок уведомления" required> 3 <textarea name="summary" placeholder="Текст уведомления" required></textarea> 4 <button type="submit">Отправить push</button> 5 </form>
На практике такая форма, лишь отладочный инструмент. В боевом проекте вызов $messaging->send() встраивается в бизнес-логику: публикация новости → уведомление подписчикам топика /topics/news.

Шаг 5: Проверка получения уведомления
После отправки уведомление приходит на экран блокировки за 1-3 секунды. Заголовок и тело, те, что переданы в Notification::create(). Тап по уведомлению запускает приложение, и через data-payload вы передаете параметры для перехода на нужный экран.

Топики дают гибкую сегментацию аудитории. Хотите разделить пользователей по платформам, создайте /topics/ios-news и /topics/android-news. По географии, /topics/users-europe. По языку, /topics/lang-ru. Комбинируйте как угодно: топики бесплатны и не имеют ограничений по количеству.

Видео: полный разбор настройки
В этом 20-минутном туториале показана сквозная интеграция Firebase Cloud Messaging с PHP-бэкендом: от создания проекта в консоли до отправки и приема push-уведомления на реальном устройстве.
⁉️🤔 Частые вопросы
Нужно ли платить за Firebase Cloud Messaging?
FCM полностью бесплатен. Google не взимает плату за отправку push-уведомлений и не устанавливает жестких квот на количество сообщений. При очень высоких объемах (миллионы в час) может включаться троттлинг, но для типичного приложения с аудиторией до сотен тысяч пользователей ограничений нет.
Обязательно ли использовать библиотеку kreait/firebase-php?
Нет, но это самый поддерживаемый PHP-пакет для Firebase на середину 2026 года. Альтернатива, работать с HTTP v1 API напрямую через Guzzle и
google/authдля получения OAuth 2.0-токена. Однако в этом случае вам придется вручную управлять сроком жизни токена, рефрешить его и отслеживать ошибки аутентификации.kreait/firebase-phpделает это автоматически.
Как отправлять уведомления конкретному устройству, а не целому топику?
Замените
withTarget('topic', $topic)наwithTarget('token', $deviceToken), где$deviceToken, FCM-токен, полученный от клиентского приложения. Токен уникален для каждой установки приложения на конкретном устройстве.
Что делать, если уведомления не приходят на iOS?
Проверьте три пункта: (1) APNs-сертификат загружен в настройках проекта Firebase (Cloud Messaging → Apple app configuration), (2) в
Info.plistдобавлен ключFirebaseAppDelegateProxyEnabledсо значениемYES, (3) устройство не находится в режиме «Не беспокоить». Также учтите, что симулятор iOS не принимает push, тестируйте только на физическом устройстве.
Можно ли отправить тихое уведомление без показа пользователю?
Да, используйте data-only message: передайте только
->withData([...])без->withNotification(...). Такое сообщение будит приложение в фоне для синхронизации данных, но не показывает визуальное уведомление. На iOS для фоновой обработки добавьте заголовокcontent-availableсо значением1.
Что изменилось и как не сломать отправку в 2026 году
Google поэтапно ужесточает требования к безопасности FCM. Главное изменение, отключение legacy HTTP API с аутентификацией по серверному ключу. Если ваш PHP-код до сих пор обращается к https://android.googleapis.com/gcm/send или https://fcm.googleapis.com/fcm/send с заголовком Authorization: key=..., уведомления не уходят с середины 2024 года.
Переход на HTTP v1 API с OAuth 2.0 через сервисный аккаунт решает эту проблему полностью. Библиотека kreait/firebase-php берет на себя получение и обновление токена, вам не нужно писать логику рефреша вручную. JSON-ключ сервисного аккаунта храните вне document root и исключите из репозитория через .gitignore.
С топиками и data-payload вы получаете гибкую маршрутизацию: новости, подписчикам /topics/news, персональные сообщения, по токену, тихую синхронизацию, через data-only message. Весь этот функционал бесплатен и работает на Android, iOS и в вебе из одного PHP-скрипта.
Проверьте текущий код отправки уведомлений в вашем проекте прямо сейчас. Если там все еще Authorization: key=, обновите на HTTP v1 API. Вопросы и нюансы интеграции пишите в комментариях.



