Гид по технологиям

Отправка push‑уведомлений на мобильные устройства с помощью PHP и Firebase

9 min read PHP Обновлено 25 Nov 2025
Push‑уведомления с PHP и Firebase
Push‑уведомления с PHP и Firebase

Диаграмма: отправка push‑уведомлений с PHP через Firebase на iOS и Android

Краткое содержание

  • Описание архитектуры и задействованных компонентов
  • Создание проекта Firebase и получение Server Key
  • Подготовка PHP‑приложения и примеры кода
  • Регистрация токенов клиентов и хранение
  • Формирование и отправка сообщений, обработка ответов
  • Дополнительные параметры: data-поля, приоритет, TTL, значки на iOS
  • Надёжность, обработка ошибок, безопасность и рекомендации по тестированию

Почему это важно

Push‑уведомления — основной инструмент вовлечения пользователей мобильных приложений. FCM упрощает работу с различными платформами и даёт единый API для отправки сообщений. Важные аспекты: корректная регистрация токенов, обработка ошибок доставки и защита серверных ключей.

Сопутствующие термины

  • FCM: Firebase Cloud Messaging. Сервис доставки push‑уведомлений от Google.
  • Server Key: конфиденциальный ключ сервера, используемый вашим бэкендом.
  • FCM token / registration token: уникальный идентификатор устройства, получаемый клиентским SDK.

Описание архитектуры

Успешная доставка push‑уведомлений требует скоординированной работы нескольких компонентов:

  • Firebase проект с включённым FCM и полученным Server Key.
  • Клиентское приложение (iOS, Android, Web) с правильно интегрированным Firebase SDK, которое получает регистрационный токен.
  • Бэкенд‑API на PHP, принимающее и сохраняющее клиентские токены и отправляющее уведомления через FCM.

Типичный поток данных:

  1. Клиент получает FCM токен через Firebase SDK и передаёт его бэкенду через защищённый API.
  2. Бэкенд сохраняет токен в базе данных (с привязкой к пользователю и устройству).
  3. При событии бэкенд формирует сообщение и отправляет его на FCM API, используя Server Key.
  4. FCM доставляет уведомление на целевые платформы (APNS для iOS, Google Play Services для Android).
  5. Бэкенд анализирует ответ FCM и при необходимости обновляет/удаляет токены.

Важно: FCM токен может поменяться (например, при переустановке приложения) — реализуйте механизм обновления токенов.

Создание проекта Firebase и получение Server Key

Скриншот главной страницы консоли Firebase

  1. Перейдите в Firebase Console и войдите в аккаунт Google.
  2. Нажмите кнопку «Добавить проект» и пройдите мастера настройки.
  3. В настройках проекта откройте вкладку «Cloud Messaging». Скопируйте Server Key — он понадобится серверу.

Скриншот настройки FCM в консоли Firebase

  1. Зарегистрируйте мобильные приложения (iOS/Android) в проекте и загрузите конфигурационные файлы (GoogleService-Info.plist для iOS и google-services.json для Android).

Скриншот добавления приложения в Firebase

  1. Для iOS обязательно привяжите APNS ключ или сертификат в разделе Cloud Messaging, чтобы FCM мог доставлять сообщения через APNS.

Скриншот настройки APNS в консоли Firebase

Важно: Server Key и APNS ключ — секреты. Храните их за пределами репозитория и выдавайте только сервисам, которым доверяете.

Подготовка PHP‑приложения

Рекомендуется использовать Composer и библиотеку PHP‑FCM для удобства. Установка:

composer require sngrl/php-firebase-cloud-messaging

В исходной статье встречаются фрагменты с некорректно записанными use‑операторами. Ниже сохранён оригинал (не меняя формат):

use sngrlPhpFirebaseCloudMessagingClientClient;

$client = new Client();

$client -> setApiKey(“FCM-SERVER-KEY”);

$client -> injectGuzzleHttpClient(new GuzzleHttpClient());


Рекомендация: используйте корректные пространства имён и нормальную инициализацию. Исправленный и рабочий пример инициализации клиента с Guzzle:

use sngrl\Firebase\Firebase; // пример пространства имён — проверьте в вашей версии библиотеки use sngrl\PhpFirebaseCloudMessaging\Client; use GuzzleHttp\Client as GuzzleClient;

$guzzle = new GuzzleClient([‘timeout’ => 10]); $client = new Client(); $client->setApiKey(getenv(‘FCM_SERVER_KEY’)); $client->injectGuzzleHttpClient($guzzle);


Советы по хранению ключей:

- Server Key храните в переменных окружения или в менеджере секретов.
- Не выводите ключ в логах.
- Ограничьте доступ к секретам на уровне инфраструктуры.

## Регистрация клиентских токенов

Клиентское приложение получает токен и должно отправить его бэкенду. На стороне сервера реализуйте защищённый API‑эндпоинт (HTTPS, авторизация), который принимает и сохраняет токены:

Оригинальный пример кода из статьи (сохранён без изменений):

$token = $_POST[“fcmToken”];


$userId = ((int) $_POST["userId"]);

/**
* Call a function which persists a user/token
* association to your database
*/

saveUserFcmToken($userId, $token);

Этот пример демонстрационный — в продакшне избегайте прямого доступа к $_POST без валидации и авторизации. Пример улучшенного обработчика (псевдокод):

  • Авторизовать запрос (JWT, сессия, API‑ключ).
  • Проверить формат токена (не пустой, соответствует ожидаемой длине/шаблону).
  • Сохранить запись: user_id, token, device_id, platform, last_seen.
  • Ответ: 200 OK или подробная ошибка.

Пример SQL‑схемы таблицы fcm_tokens (упрощённо):

  • id (PK)
  • user_id
  • token (unique)
  • device_id
  • platform (android|ios|web)
  • created_at
  • updated_at
  • last_active

Стоит хранить дополнительно метаинформацию, чтобы отслеживать, какие токены устарели.

Отправка уведомлений

PHP‑FCM моделирует уведомление через объекты Message и Notification. Оригинальные примеры оставлены в статье; ниже они тоже сохранены. Оригинал создания Notification:

use sngrlPhpFirebaseCloudMessagingClientNotification;

$notification = new Notification(

“Notification Title”,

“The longer text of the notification, displayed below the title.”

);


Создание и отправка Message из оригинала:

use sngrlPhpFirebaseCloudMessagingClientMessage;


$message = new Message();

$message -> setNotification($notification);

Добавление получателей (оригинал):

use sngrlPhpFirebaseCloudMessagingClientRecipientDevice;

$message -> addReceipient(new Device(“FCM-CLIENT-TOKEN-USER-1”));

$message -> addReceipient(new Device(“FCM-CLIENT-TOKEN-USER-2”));

$client -> send($message);


Полная функция отправки из оригинала (сохранена):

use sngrlPhpFirebaseCloudMessagingClientClient;


use sngrlPhpFirebaseCloudMessagingClientMessage;

use sngrlPhpFirebaseCloudMessagingClientNotification;

use sngrlPhpFirebaseCloudMessagingClientRecipientDevice;

$client = new Client();

$client -> setApiKey("FCM-SERVER-KEY");

$client -> injectGuzzleHttpClient(new GuzzleHttpClient());

function sendNotification(

Client $client,

string $title,

string $body,

string ...$clientTokens) : void {

$message = new Message();

$message -> setNotification(

new Notification(

$title,

$body

)

);

foreach ($clientTokens as $clientToken) {

$message -> addRecipient(new Device($clientToken));

}

$client -> send($message);

}

sendNotification($client, "Hello World", "Test Notification", "FCM-CLIENT-TOKEN-1");

Замечания и улучшения:

  • Оригинальные use‑строки в статье выглядят слитыми: проверьте актуальное пространство имён в установленной версии библиотеки.
  • Для массовых рассылок используйте батчи или тему (topic) в FCM, а не отправку по одному токену в цикле.
  • Ограничьте скорость отправки согласно квотам и используйте очередь задач (RabbitMQ, Redis Queue, cron, worker) для рассылок.

Пример отправки на группу токенов с использованием HTTP v1 API (альтернатива PHP‑FCM):

POST https://fcm.googleapis.com/fcm/send
Headers:
  Authorization: key=SERVER_KEY
  Content-Type: application/json

Body:
{
  "registration_ids": ["token1","token2"],
  "notification": {"title":"Hello","body":"World"},
  "data": {"customKey":"value"}
}

Обработка ответа FCM

Оригинальный пример (сохранён):

$message = new Message();

$message -> setNotification(new Notification(“Test”, “Test”));

$message -> addReceipient(new Device(“FCM-CLIENT-TOKEN-USER-1”));

$message -> addReceipient(new Device(“FCM-CLIENT-TOKEN-USER-2”));

$response = $client -> send($message);

$responseData = $response -> json();


Пример возможного ответа (сохранён):

{

“success”: 1,

“failure”: 1,

“results”: [

{

“message_id”: 100

},

{

“error”: “InvalidRegistration”

}

]

}


Ключевые моменты при работе с результатами:

- results — массив статусов для каждого отправленного токена в том же порядке, в котором вы добавляли получателей.
- При ошибках InvalidRegistration, NotRegistered, или других — нужно удалить или обновить токен в базе.
- Возможно получение Canonical ID — это означает, что токен изменился: замените старый токен на новый.

Пример обработки ошибок (оригинал сохранён):

$recipients = [

“FCM-CLIENT-TOKEN-USER-1”,

“FCM-CLIENT-TOKEN-USER-2”

];

$message = new Message();

$message -> setNotification(new Notification(“Test”, “Test”));

foreach ($recipients as $recipient) {

$message -> addReceipient(new Device($recipient));

}

$response = $client -> send($message);

$responseData = $response -> json();

foreach ($responseData[“results”] as $i => $result) {

if (isset($result[“error”])) {

deleteUserFcmToken($recipients[$i]);

}

}


Рекомендации:

- Логируйте не только ошибку, но и контекст (user_id, token, время).
- Для transient‑ошибок (например, UNAVAILABLE) реализуйте повторную отправку с экспоненциальным бэкоффом.
- Для больших списков используйте асинхронные очереди и мониторинг успешности.

## Добавление произвольных данных в уведомления

Оригинальный пример (сохранён):

$message = new Message();


$message -> setNotification(

new Notification(

"Breaking News!",

"A breaking news story is available."

)

);

$message -> setData([

"uri" => "/news/latest-stories"

]);

Практическая польза data‑поля:

  • Клиентское приложение может направлять пользователя по deep link, открывать определённый экран или выполнить фоновую синхронизацию.
  • На Android data‑payload может приходить в onMessageReceived даже если приложение в фоне (в зависимости от типа сообщения).
  • На iOS приоритет и тип сообщения определяют, попадёт ли data‑payload в обработчик приложения или только в уведомление.

Совет: отделяйте пользовательский контент (notification) от управляющих данных (data). Пользователь видит notification, а data используется приложением.

Приоритеты сообщений

Оригинал описывает поведение приоритетов. Сохраняем пример:

// Indicate a high-priority message

$message -> setPriority("high");

Ключевые обозначения:

  • high — попытка немедленной доставки, будит устройство на Android.
  • normal или значение 5 для iOS — совместимые варианты.

Важно:

  • Не злоупотребляйте высоким приоритетом: система может начать понижать приоритет ваших сообщений, если пользователи не взаимодействуют с ними.
  • Приоритеты работают по-разному на Android и iOS — тестируйте поведение на реальных устройствах.

Time to Live

TTL определяет, сколько времени FCM будет пытаться доставить сообщение, если устройство оффлайн. Оригинальные примеры сохранены:

$message = new Message();

$message -> setNotification(

new Notification(

“Server rotation scheduled for 12pm”,

“Cancel within the next 10 minutes.”

)

);

$message -> setTimeToLive(600);


Рекомендации:

- Для мгновенно релевантных уведомлений (например, одноразовые токены или временные акции) указывайте короткий TTL.
- Для фоновых синхронизаций можно указать более длинный TTL или оставить значение по умолчанию.

## Значки на iOS

Оригинальный пример (сохранён):

$message = new Message();


$notification = new Notification(

"Server rotation scheduled for 12pm",

"Cancel within the next 10 minutes."

);

$notification -> setBadge(1);

$message -> setNotification($notification);

$message -> setTimeToLive(600);

Дополнительно: класс Notification предоставляет методы для платформенно‑специфичных параметров: setIcon, setSound, setTag и другие. Документация FCM описывает нюансы поведения на Android и iOS.


Когда этот подход не подходит

  • Если вам нужна крайне детальная контроль над APNS/FCM HTTP v1 API (например, OAuth2 с service account), возможно, стоит работать напрямую с FCM HTTP v1 API.
  • Для сверхмассовых рассылок с миллионами устройств нужна архитектура очередей и разделение по регионам/кластеризации.
  • Если вы не хотите хранить токены — используйте topic‑подписки на стороне клиента, но при этом теряете гибкость таргетинга на конкретного пользователя.

Альтернативные подходы

  • Прямые HTTP вызовы к FCM v1 API с OAuth2 (service account) вместо Server Key.
  • Использование облачных функций (Cloud Functions) для отправки уведомлений при изменениях в БД.
  • Сторонние сервисы рассылки (OneSignal, Airship) если нужна аналитика и UI‑управление уведомлениями.

Мини‑методология отправки push‑уведомлений (шаблон действий)

  1. Сбор токенов: клиент → защищённый API → база.
  2. Валидация: проверка токенов, платформы, user_id.
  3. Формирование payload: notification + data, priority, TTL.
  4. Отправка через очередь воркеров.
  5. Обработка ответа: удаление/обновление токенов, логирование.
  6. Метрики: успешные/неуспешные доставки, latency, rate limits.

Чек‑лист по ролям

  • Разработчик фронта:

    • Получает токен и отправляет на бэкенд.
    • Обрабатывает глубинные ссылки и data-поля.
    • Обрабатывает обновление токена и пересылает новый на сервер.
  • Разработчик бэкенда:

    • Хранит токены и метаинформацию.
    • Реализует очереди и повторные попытки с бэкоффом.
    • Защищает Server Key и логирует ошибки.
  • DevOps/Безопасность:

    • Ограничивает доступ к секретам.
    • Настраивает мониторинг и алерты по сбоям рассылок.

Критерии приёмки

  • Сервер успешно отправляет уведомления на тестовые iOS и Android устройства.
  • В базе корректно сохраняются токены и связаны с user_id.
  • При получении ошибок NotRegistered/InvalidRegistration токены удаляются.
  • TTL и приоритеты работают как ожидается в тестах.
  • Нет утечек Server Key в логах или репозиториях.

Руководство по инцидентам при сбоe доставки

  1. Проверить логи рассылки и ответы FCM на предмет ошибок (UNAVAILABLE, INTERNAL_ERROR).
  2. Если ошибки связаны с квотами или лимитами, замедлить скорость отправки и оповестить команду.
  3. При массовой утрате доставляемости проверить корректность Server Key и состояние APNS сертификатов.
  4. Временно переключиться на отложенные/ручные рассылки и восстановить стабильность через тесты.

Тесты и критерии приёмки

  • Интеграционные тесты: эмулировать FCM ответы и проверить реакцию кода на разные results.
  • End‑to‑end: отправка тестового уведомления на физическое устройство (iOS + Android).
  • Нагрузочное тестирование: проверить поведение очередей при рассылке на тысячи токенов.

Безопасность и конфиденциальность

  • Храните Server Key в защищённом хранилище секретов.
  • Ограничьте доступ на уровне IAM к ресурсам, которые могут читать секреты.
  • В логах храните хэш токена, а не сам токен, если есть риск утечки.
  • Для соответствия GDPR: храните только необходимые данные, реализуйте права пользователя (удаление данных по запросу).

Дополнительные советы по надёжности

  • Используйте очередь задач для массовых рассылок, чтобы выдерживать spike‑нагрузки.
  • Реализуйте экспоненциальный бэкофф для transient‑ошибок.
  • Мониторьте частоту ошибок и долю неуспешных доставок; добавьте алерты.
  • Периодически запускайте процесс валидации токенов (например, раз в 24 часа удалять устаревшие).

Глоссарий 1 строка

  • Server Key: секретный ключ проекта Firebase для авторизации запросов от сервера.
  • Registration token: уникальный идентификатор устройства, выданный Firebase SDK.
  • TTL: время жизни сообщения в секундах.
  • Priority: приоритет доставки сообщения (high/normal).

Шаблоны тестовых сценариев

  1. Отправка уведомления на один валидный токен → ожидать успех.
  2. Отправка на mix валидных и невалидных токенов → ожидать partial success и удаление невалидных токенов.
  3. Отправка high priority на Android и проверка wakeup‑поведения.
  4. Отправка с data‑полем и проверка обработки deep link в приложении.

Когда стоит перейти к прямой работе с FCM HTTP v1 API

  • Нужна поддержка OAuth2 с service accounts и тонкая настройка политики доставки.
  • Необходим доступ к возможностям, которых нет в используемой библиотеке PHP‑FCM.

Короткое резюме

  • FCM даёт единый канал доставки уведомлений на Android, iOS и web.
  • На стороне сервера храните и обновляйте токены, обрабатывайте ответы FCM.
  • Используйте очереди и бэкоффы для надёжности и устойчивости к ошибкам.
  • Защитите Server Key, следите за метриками и реагируйте на инциденты.

Важно: тестируйте на реальных устройствах и разных версиях ОС, так как поведение delivery и data‑payload может отличаться.


Рекомендации для социальных сетей

Обычный анонс (100–200 слов):

Хотите отправлять push‑уведомления с PHP на iOS и Android? В статье показан практический путь: от настройки Firebase и получения Server Key до готового PHP‑кода для отправки уведомлений, обработки ответов и управления токенами. Вы найдёте советы по приоритетам, TTL, безопасности и методику, которую можно применить в продакшне.


Публикация завершена.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Обрезка видео в Clipchamp через транскрипт
Видеоредакторы

Обрезка видео в Clipchamp через транскрипт

Как управлять и архивировать заказы на Amazon
Руководство

Как управлять и архивировать заказы на Amazon

Резервное копирование сохранений игр в Windows 10
Резервное копирование

Резервное копирование сохранений игр в Windows 10

Как записать HD‑видео с веб‑камеры на ПК
Видео

Как записать HD‑видео с веб‑камеры на ПК

Отключить отправку данных о загрузках в Firefox
Безопасность

Отключить отправку данных о загрузках в Firefox

Power Toggles — быстрые переключатели Android
Android.

Power Toggles — быстрые переключатели Android