Уведомления Expo не работают на Android в приложении React Native
Я разрабатываю приложение React Native с использованием Expo GO и реализовал push-уведомления. Хотя уведомления успешно приходят на устройствах iOS, они не отображаются на устройствах Android. Я использую .NET API для отправки уведомлений.
Может ли кто-нибудь помочь мне определить, что может вызывать эту проблему? Кроме того, я создал dev-сборку, но не уверен, как ее использовать или чем она отличается от Expo GO в отношении уведомлений Expo.
Вот моя текущая настройка уведомлений:
import { useState, useEffect, useRef } from 'react';
import { Text, View, Button, Platform, Alert } from 'react-native';
import * as Device from 'expo-device';
import * as Notifications from 'expo-notifications';
import Constants from 'expo-constants';
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldPlaySound: true,
shouldSetBadge: true,
shouldShowBanner: true,
shouldShowList: true,
}),
});
export default function Notification() {
const [expoPushToken, setExpoPushToken] = useState(''); //это уникальный идентификатор
const [channels, setChannels] = useState([]);
const [notification, setNotification] = useState(
undefined
); //это уведомление
useEffect(() => {
registerForPushNotificationsAsync().then(token => token && setExpoPushToken(token));
if (Platform.OS === 'android') {
Notifications.getNotificationChannelsAsync().then(value => setChannels(value ?? []));
}
//слушатели
const notificationListener = Notifications.addNotificationReceivedListener(notification => {
setNotification(notification);
}); //для полученных уведомлений
//ЭТО КЛЮЧЕВОЙ МОМЕНТ
useEffect(() => {
const subscription = Notifications.addNotificationResponseReceivedListener(response => {
const { type, bunjoNovostiId } = response.notification.request.content.data;
if(type === "news" && bunjoNovostiId != null){
navigate('Akcija');
}
});
return () => {
subscription.remove();
};
}, []);
return () => {
notificationListener.remove();
responseListener.remove();
};
}, []);
}
export async function registerForPushNotificationsAsync() {
let token;
if (Platform.OS === 'android') {
await Notifications.setNotificationChannelAsync('myNotificationChannel', {
name: 'A channel is needed for the permissions prompt to appear',
importance: Notifications.AndroidImportance.MAX,
vibrationPattern: [0, 250, 250, 250],
lightColor: '#FF231F7C',
});
}
if (Device.isDevice) {
const { status: existingStatus } = await Notifications.getPermissionsAsync();
let finalStatus = existingStatus;
if (existingStatus !== 'granted') {
const { status } = await Notifications.requestPermissionsAsync();
finalStatus = status;
}
if (finalStatus !== 'granted') {
Alert.alert('Вы не будете получать уведомления.');
return;
}
try {
const projectId =
Constants?.expoConfig?.extra?.eas?.projectId ?? Constants?.easConfig?.projectId;
if (!projectId) {
throw new Error('Project ID not found');
}
token = (
await Notifications.getExpoPushTokenAsync({
projectId,
})
).data;
} catch (e) {
token = `${e}`;
}
} else {
alert('Для push-уведомлений необходимо использовать физическое устройство');
}
return token;
}
Что может мешать работе уведомлений на Android, и как dev-сборки влияют на функциональность уведомлений по сравнению с Expo GO?
Push-уведомления не работают на Android в вашем приложении Expo React Native: полное руководство
Проблема с неработающими push-уведомлениями на Android в вашем приложении Expo React Native является распространенной, в первую очередь потому, что Expo GO не поддерживает удаленные push-уведомления на устройствах Android - вы должны использовать development build или standalone приложение. Хотя ваши уведомления работают идеально на iOS из-за разных требований реализации, Android требует конкретной конфигурации и процессов сборки, которые Expo GO не может предоставить.
Содержание
- Почему Expo GO не поддерживает push-уведомления на Android
- Development Build против Expo GO для уведомлений
- Распространенные проблемы с уведомлениями на Android
- Требования к конфигурации FCM
- Проблемы в вашей реализации кода
- Пошаговые решения
- Тестирование и верификация
Почему Expo GO не поддерживает push-уведомления на Android
Основная проблема, с которой вы сталкиваетесь, обусловлена архитектурными ограничениями Expo. Согласно официальной документации Expo, “функциональность push-уведомлений (удаленных уведомлений), предоставляемая expo-notifications, недоступна в Expo Go на Android начиная с SDK 53. Требуется development build для использования push-уведомлений.”
Это ограничение существует потому, что:
- Expo GO использует общие учетные данные Expo для разработки
- Android требует специфичных для приложения конфигураций Firebase Cloud Messaging (FCM)
- Политики Google Play Store требуют правильного подписания приложений и управления ключами
- Push-уведомления требуют глубокой интеграции с системой, что предотвращает песочница Expo GO
Как указано в FAQ Expo, “Expo Go использует учетные данные Expo, что позволяет работать с уведомлениями в разработке. Когда вы собираете приложение для магазинов приложений, вам нужно сгенерировать и использовать свои собственные…”
Development Build против Expo GO для уведомлений
Ключевое различие между этими средами для push-уведомлений:
| Функция | Expo GO (Android) | Development Build/Standalone приложение |
|---|---|---|
| Push-уведомления | ❌ Не поддерживается | ✅ Полностью поддерживается |
| Локальные уведомления | ✅ Поддерживается | ✅ Поддерживается |
| Интеграция FCM | ❌ Недоступна | ✅ Требуется |
| Токен устройства | Ограниченная функциональность | Полный доступ к токену устройства |
| Тестирование | Только базовое | Полноценное тестирование возможно |
Как объясняется в документации Expo, вам нужно “собирать с помощью EAS Build” для правильной работы push-уведомлений на Android.
Распространенные проблемы с уведомлениями на Android
Несколько специфичных проблем часто влияют на работу уведомлений на Android:
1. Отсутствует конфигурация FCM
- Проблема: Отсутствуют или неверные ключи Firebase Cloud Messaging
- Симптомы: Уведомления работают в Expo GO, но не работают в standalone сборках
- Подтверждение: Пользователь Reddit отметил: “Убедитесь, что вы настроили ключи FCM для Android. В противном случае push-уведомления не работают в standalone сборках.”
2. Проблемы с каналами уведомлений
- Проблема: Android требует правильной настройки каналов уведомлений
- Симптомы: Уведомления появляются, но не издают звук или не отображаются правильно
- Подтверждение: Некоторые пользователи сообщают, что уведомления только “показываются в виде значка на верхней панели” без всплывающего функционала
3. Проблемы реализации слушателя
- Проблема: Слушатели уведомлений не правильно активируются на Android
- Симптомы: Нажатие на уведомления не приводит к навигации к ожидаемым экранам
- Подтверждение: Обсуждения на Stack Overflow упоминают “слушатель уведомлений не работает для Android в react native expo app - слушатель не активируется для Android, когда я нажимаю на уведомление”
Требования к конфигурации FCM
Чтобы push-уведомления работали на Android, вы должны правильно настроить Firebase Cloud Messaging:
-
Создайте проект Firebase
- Перейдите в Firebase Console
- Создайте новый проект для вашего приложения
-
Добавьте Android приложение
- Зарегистрируйте имя пакета вашего Android приложения
- Скачайте файл
google-services.json
-
Настройте EAS Build
basheas build:configure
Это настроит необходимые файлы конфигурации Android
-
Настройте переменные окружения
- Добавьте ваш серверный ключ FCM в секреты EAS
- Настройте ID проекта в конфигурации вашего приложения
Как объясняется в руководстве Expo по FCM, “узнайте, как отправлять уведомления с помощью FCM и APNs” для правильной настройки.
Проблемы в вашей реализации кода
Анализируя ваш код уведомлений, есть несколько проблем, которые нужно исправить:
1. Неопределенный слушатель ответа
// В вашем коде есть эта проблема:
useEffect(() => {
const subscription = Notifications.addNotificationResponseReceivedListener(response => {
// ...
});
return () => {
subscription.remove();
};
}, []);
// Но responseListener используется до определения в очистке:
return () => {
notificationListener.remove();
responseListener.remove(); // ❌ responseListener не определен здесь
};
2. Ограничения токена Expo
Метод getExpoPushTokenAsync() имеет ограничения в standalone сборках. Для Android следует использовать токен FCM устройства вместо этого.
3. Отсутствует обработка ошибок
Код не правильно обрабатывает случаи, когда получение токена не удается в standalone сборках.
Пошаговые решения
Решение 1: Создайте Development Build
# Сначала настройте EAS
eas build:configure
# Создайте development build
eas build --platform android --profile development
Решение 2: Исправьте ваш код уведомлений
import * as Notifications from 'expo-notifications';
import Constants from 'expo-constants';
export default function Notification() {
const [expoPushToken, setExpoPushToken] = useState('');
const [notification, setNotification] = useState(undefined);
useEffect(() => {
registerForPushNotificationsAsync().then(token => {
if (token) setExpoPushToken(token);
});
// Настройте каналы уведомлений для Android
if (Platform.OS === 'android') {
setupNotificationChannels();
}
// Добавьте слушатели
const notificationListener = Notifications.addNotificationReceivedListener(setNotification);
const responseListener = Notifications.addNotificationResponseReceivedListener(handleNotificationResponse);
return () => {
notificationListener.remove();
responseListener.remove();
};
}, []);
const handleNotificationResponse = (response) => {
const { type, bunjoNovostiId } = response.notification.request.content.data;
if(type === "news" && bunjoNovostiId != null){
// Навигация к вашему экрану здесь
console.log('Навигация к новости:', bunjoNovostiId);
}
};
const setupNotificationChannels = async () => {
if (Platform.OS === 'android') {
await Notifications.setNotificationChannelAsync('myNotificationChannel', {
name: 'Мои уведомления',
importance: Notifications.AndroidImportance.MAX,
vibrationPattern: [0, 250, 250, 250],
lightColor: '#FF231F7C',
});
}
};
}
export async function registerForPushNotificationsAsync() {
if (!Device.isDevice) {
alert('Для push-уведомлений необходимо использовать физическое устройство');
return;
}
// Запрос разрешений
const { status: existingStatus } = await Notifications.getPermissionsAsync();
let finalStatus = existingStatus;
if (existingStatus !== 'granted') {
const { status } = await Notifications.requestPermissionsAsync();
finalStatus = status;
}
if (finalStatus !== 'granted') {
Alert.alert('Разрешение на уведомления не предоставлено');
return;
}
// Получение токена с правильным ID проекта
const projectId = Constants.expoConfig.extra.eas.projectId;
if (!projectId) {
throw new Error('ID проекта не найден в конфигурации приложения');
}
return await Notifications.getExpoPushTokenAsync({
projectId,
});
}
Решение 3: Настройте FCM для продакшена
-
Получите учетные данные FCM:
- В Firebase Console перейдите в Настройки проекта
- В разделе Cloud Messaging найдите Server Key и Sender ID
-
Настройте секреты EAS:
basheas secret:create FCM_SERVER_KEY=ваш_серверный_ключ_здесь eas secret:create FCM_SENDER_ID=ваш_sender_id_здесь
-
Обновите app.json:
json{ "expo": { "android": { "package": "com.yourcompany.yourapp" }, "extra": { "eas": { "projectId": "ваш-id-проекта" } } } }
Тестирование и верификация
Тестирование вашего Development Build
- Установите development build на ваше Android устройство
- Убедитесь, что вы получаете push-уведомления
- Протестируйте ответы на уведомления и навигацию
Распространенные проблемы тестирования
- Уведомления появляются, но не издают звук: Проверьте настройки важности канала уведомлений
- Уведомления не появляются: Проверьте конфигурацию FCM и сетевые разрешения
- Слушатели не активируются: Убедитесь в правильной очистке и настройке слушателей
Как предлагается в руководстве по устранению неполадок Expo, “это указывает на то, что вы либо неправильно настроили учетные данные, либо вообще не настроили их в вашем продакшн приложении.”
Заключение
Основная проблема, мешающая работе ваших Android уведомлений, заключается в том, что Expo GO не поддерживает push-уведомления на Android - вы должны использовать development build или standalone приложение. Ключевые выводы:
- Используйте Development Builds: Создайте EAS development build для правильной поддержки push-уведомлений на Android
- Правильно настройте FCM: Настройте Firebase Cloud Messaging с правильными серверными ключами и именами пакетов
- Исправьте проблемы в коде: Устраните неопределенный responseListener и улучшите обработку ошибок
- Тестируйте на физических устройствах: Уведомления не будут работать правильно на эмуляторах для standalone сборок
Для непрерывной разработки рассмотрите использование локальных уведомлений в Expo GO для тестирования UI компонентов, в то время как использование development builds для end-to-end тестирования push-уведомлений. Переход от Expo GO к standalone сборкам требует тщательного внимания к конфигурации FCM и правильной настройке сборки, но после реализации уведомления на Android будут работать как ожидается.