Каталог помилок Push
Кожен пункт починається із симптому, який видно наочно. Ці системи ламаються, маскуючись одна під одну, тож ідіть від того, що бачите, а не від того, де підозрюєте баг.
Помилки відправки FCM
| Відповідь | Типова причина | Рішення |
|---|---|---|
404 UNREGISTERED / NotRegistered | Бекенд надсилає installation id туди, де message.token очікує registration token — або збережений токен застарів. | Надсилайте fcmToken при реєстрації й перезаписуйте його щоразу. Видаляйте інсталяцію, коли FCM відповідає UNREGISTERED. |
400 INVALID_ARGUMENT | Та сама помилка, що й вище. Обидва коди повертають за одну й ту саму причину. | Орієнтуйтеся на «прийнято чи відхилено», а не на конкретний код. |
403 | Сервісний акаунт належить іншому проєкту Firebase, ніж застосунок. | Звірте project_id у google-services.json, GoogleService-Info.plist і сервісному акаунті. |
PERMISSION_DENIED: Firebase Cloud Messaging API has not been used in project … | Не увімкнено FCM API (V1). | Увімкніть у Firebase → Project settings → Cloud Messaging. |
Нічого не реєструється взагалі
Жоден запит не доходить до сервісу, помилки теж немає.
Реєстрація відпрацювала й впала там, де виняток проковтнули. Шукайте спільний try навколо installation id і токена: збій токена обнуляє ID, і виклик пропускає реєстрацію повністю. Беріть їх незалежно.
FCM registration token: Object is not a function.
RNFirebase v26 прибрав викличний неймспейс messaging(), тому module.default ?? module повертає обʼєкт модуля. Використовуйте модульний API.
Запити надсилаються й отримують відповідь, але в сервісі немає записів.
Перевірте хост. Сервіс push — це restapi.smsbat.com; сусідній хост може прийняти й відкинути запит, тож застосунок бачить успіх, а дані нікуди не потрапляють.
Реєстрація під ID, який збігається з чужим.
Додайте префікс до externalUserId — operator-497, а не 497. ID операторів і клієнтів ділять один простір.
Push приходить, але нічого не зʼявляється
Нічого на екрані, поки застосунок відкритий.
Повідомлення data-only за задумом, тому система нічого не малює. Foreground-обробник має сам побудувати сповіщення з data.
Нічого, поки застосунок згорнутий або закритий. Причина та сама, обробник інший. Background-обробник теж має малювати сповіщення й має бути зареєстрований на рівні модуля — обробник, підключений з екрана, не існує на момент запуску headless-задачі.
Зʼявляється, але беззвучно на Android.
Канал не було створено до показу сповіщення, або не видано дозвіл POST_NOTIFICATIONS на Android 13+.
Push зʼявляється, але статус не доходить до бекенда
Це найдорожчий випадок: каскад вважає, що push не пройшов, і тарифікує SMS, яку користувач уже прочитав.
Статусів немає взагалі, на обох платформах.
На Android за MESSAGING_EVENT конкурують три сервіси, на iOS обидві бібліотеки претендують на UNUserNotificationCenter.delegate. Якщо застосунок слухає лише через expo-notifications, а перемагає сервіс RNFirebase, не спрацює жоден слухач. Слухайте з обох боків і дедуплікуйте за guid.
Статуси приходять двічі на одне повідомлення.
Повідомлення дійшло обома шляхами, або локально перемальоване сповіщення повернулося через слухач expo-notifications. Дедуплікуйте за data.guid.
delivered приходить лише коли застосунок відкритий.
На Android повідомлення з блоком notification малює система, і воно не доходить до JS, доки на нього не натиснуть. Перевірте, чи не повернувся блок notification у payload.
Особливості iOS
Працює на Android, тиша на iOS. Перевірте APNs auth key у Firebase, в обох слотах. Типовий недогляд — завантажено лише development-ключ, тоді як TestFlight працює в production.
FCM-токен не зʼявляється, рядок APNs-токена порожній.
registerDeviceForRemoteMessages() повертається до того, як прийде APNs-токен. Опитуйте getAPNSToken(), перш ніж просити токен у FCM.
На симуляторі все порожнє. Так і має бути. Apple не видає push-токен симулятору. Тестуйте на пристрої.
Дозвіл на сповіщення видано, але нічого немає.
Переконайтеся, що присутній UIBackgroundModes: ["remote-notification"], потім перевірте APNs-ключ.
Результати, які вводять в оману
Тестове повідомлення з консолі Firebase приходить, а виклик API — ні. Так і буде, і це збиває з пантелику: консоль спершу перетворює installation id на токен, а API v1 цього не робить. Зараховується лише результат API. Успішний тест із консолі підтверджує, що пристрій, дозволи, APNs-ключ і проєкт справні — і нічого не каже про те, що надсилає бекенд.
Найдешевша перевірка
FID — приблизно 22 символи без двокрапки. Registration token — 140+ символів із двокрапкою приблизно на 23-й позиції. Якщо логувати довжину токена поруч із кожним збоєм відправки, це стає видно назавжди.
Питання, які варто поставити до початку налагодження
- Який ідентифікатор бекенд надсилає насправді? Не який має намір надсилати.
- Чи він актуальний? Пристрій, перевстановлений після реєстрації, має інший FID та інший токен.
- Чи встановлено збірку збоку? Збірка зі стора не оновиться поверх APK з іншим підписом.
- Яка збірка на пристрої? Версія з екрана налаштувань, а не з консолі.
- Чи справді артефакт містить той проєкт Firebase, який ви думаєте?