Діагностика та усунення помилок у Push-сповіщеннях (Troubleshooting & Pitfalls)
Діагностика та усунення помилок у Push-сповіщеннях (Troubleshooting & Pitfalls)
Інтеграція Push-сповіщень зачіпає 4 незалежні системи: ваш мобільний застосунок, Firebase Console, сервіси FCM/APNs та бекенд SMSBAT Omni. Більшість проблем виникає через те, що кожна з цих систем у разі збою поводиться мовчки або повертає оманливі помилки.
У цьому посібнику зібрані типові пастки розробки та покрокова процедура діагностики живих поломок.
1. Три ідентифікатори, які часто плутають
| Ідентифікатор | Як виглядає | Для чого використовується |
|---|---|---|
| Firebase Installation ID (FID) | fA9kQ2xRTb2mLp0WYs4nEv | Ідентифікує інсталяцію. Ключ upsert. НЕ призначений для відправки! |
| FCM Registration Token | fA9kQ2xRTb2mLp0WYs4nEv:APA91b… (~163 символів) | Єдине значення, яке приймає поле message.token для доставки пуша. |
| Expo Push Token | ExponentPushToken[...] | Власний токен Expo Service. Не використовується в прямому Push API SMSBAT. |
⚠️ Зверніть увагу: FCM токен починається з FID, тому їх часто плутають у коді.
2. Сім пасток інтеграції (і як їх уникнути)
1. RNFirebase v26 та видалення виклику messaging()
У версіях @react-native-firebase/messaging v26+ старий синтаксис виклику виклику імпорту повертає undefined.
- ❌ Помилка:
Object is not a functionпри спробі отримати токен. - ✅ Рішення: Використовуйте тільки модульний API:
import messaging, { getMessaging, getToken, getAPNSToken } from '@react-native-firebase/messaging'; const msgInstance = getMessaging(); const fcmToken = await getToken(msgInstance);
2. Одиничний try/catch блок для FID та Token
Якщо ви отримуєте FID та FCM токен в одному блоці try, і виклик getToken() видає помилку (що часто буває на iOS до авторизації), ваш код втрачає і FID, і токен.
- ✅ Рішення: Отримуйте FID та FCM токен у окремих блоках
try/catch. Відсутність токена не повинна блокувати реєстрацію інсталяціїregisterInstallation.
3. Затримка генерації APNs токена на iOS
Метод registerDeviceForRemoteMessages() повертає проміс відразу після запиту. Сам APNs токен приходить від Apple із затримкою.
- ✅ Рішення: Зробіть циклічне опитування
getAPNSToken()(10 спроб по 500мс) перед викликомgetToken().
4. Конфлікт сервісів обробки пушів на Android (Expo vs RNFirebase)
Якщо в застосунку одночасно встановлені expo-notifications та @react-native-firebase/messaging, в AndroidManifest.xml реєструються два конкуруючих сервіси FirebaseMessagingService.
- ⚠️ Android віддає пуш тільки одному з них. Якщо перемагає RNFirebase, а слухач стоїть в Expo, сповіщення не відобразиться і колбек
deliveredне надійде. - ✅ Рішення: Підписуйтесь на події на обох рівнях і робіть дедуплікацію за
data.guid.
5. Повідомлення Data-only не малюються системою автоматично
Бекенд SMSBAT надсилає data-only повідомлення для того, щоб мобільний застосунок мав можливість відправити статус delivered ще до того, як користувач відкрив пуш.
- ⚠️ Системний банер не показується автоматично!
- ✅ Рішення: Застосунок повинен сам малювати локальне сповіщення (візуальний банер) у фоновому та активному режимі.
6. Передача FID замість FCM Токена
Офіційний Send test message у Firebase Console приймає FID, тому що сам конвертує його в токен. Проте REST API v1 вимагає тільки FCM registration token.
- ❌ Якщо передати bare FID у поле токена, Firebase поверне
404 UNREGISTERED.
7. Оновлення токенів (Token Rotation)
При перевстановленні застосунку або очищенні даних девайс отримує новий FID та токен.
- ✅ Бекенд повинен робити
upsertза пароюexternalUserId+platform, а при отриманні відповідіUNREGISTEREDвід FCM — деактивувати застарілу інсталяцію.
3. Швидка діагностика живої поломки
Якщо пуші не доходять або каскад не зупиняється, перевірте ланцюжок за кроками:
- Чи є токен на пристрої? (Виведіть діагностичний екран у застосунку). Якщо порожньо — проблема на стороні мобільного коду чи дозволів iOS/Android.
- Чи доходить тестовий cURL запит напряму у FCM V1? Якщо так — мобільний застосунок та ключі Firebase налаштовані вірно, проблема в бекенд-відправнику.
- Чи немає помилки
SenderIdMismatch? Свідчить про те, щоgoogle-services.jsonу застосунку належить іншому Firebase-проекту, ніж Service Account JSON на бекенді SMSBAT. - Чи немає помилки
ThirdPartyAuthError? Термін дії сервісного акаунту Firebase закінчився або ключ заблоковано. Оновіть JSON-файл у панелі Omni.