Push-уведомления
Уведомления удерживают пользователя. Бывают локальные и push (с сервера).
Expo Notifications
npx expo install expo-notifications expo-device expo-constants
Разрешение
import * as Notifications from 'expo-notifications';
const { status } = await Notifications.requestPermissionsAsync();
if (status !== 'granted') return;
Получение токена
import Constants from 'expo-constants';
async function registerForPush() {
const { status } = await Notifications.requestPermissionsAsync();
if (status !== 'granted') return null;
const projectId = Constants.expoConfig?.extra?.eas?.projectId;
const token = (await Notifications.getExpoPushTokenAsync({ projectId })).data;
await api.post('/devices', { token, platform: Platform.OS });
return token;
}
Токен отправляется на сервер. Сервер шлёт уведомления через Expo Push API.
Настройка Android-канала
if (Platform.OS === 'android') {
await Notifications.setNotificationChannelAsync('default', {
name: 'Основной',
importance: Notifications.AndroidImportance.HIGH,
vibrationPattern: [0, 250, 250, 250],
lightColor: '#c1442e',
});
}
Обработчик в приложении
Notifications.setNotificationHandler({
handleNotification: async () => ({
shouldShowAlert: true,
shouldPlaySound: true,
shouldSetBadge: true,
}),
});
Слушатели
useEffect(() => {
const receivedSub = Notifications.addNotificationReceivedListener((notification) => {
console.log('получено', notification);
});
const responseSub = Notifications.addNotificationResponseReceivedListener((response) => {
const data = response.notification.request.content.data;
// навигация по data
if (data.type === 'post') {
navigation.navigate('PostDetails', { id: data.id });
}
});
return () => {
receivedSub.remove();
responseSub.remove();
};
}, []);
Локальные уведомления
await Notifications.scheduleNotificationAsync({
content: {
title: 'Напоминание',
body: 'Не забудьте про задачу',
data: { taskId: 5 },
},
trigger: { seconds: 60 },
});
С датой:
trigger: { date: new Date(Date.now() + 60 * 60 * 1000) },
Ежедневно:
trigger: { hour: 9, minute: 0, repeats: true },
Бейдж
await Notifications.setBadgeCountAsync(5);
Отмена
await Notifications.cancelAllScheduledNotificationsAsync();
Отправка с сервера
Сервер отправляет через Expo Push API:
curl -X POST https://exp.host/--/api/v2/push/send \
-H "Content-Type: application/json" \
-d '{
"to": "ExponentPushToken[xxx]",
"title": "Новое сообщение",
"body": "У вас 1 новое сообщение",
"data": { "type": "chat", "chatId": 5 }
}'
Или через Laravel:
use Illuminate\Support\Facades\Http;
Http::post('https://exp.host/--/api/v2/push/send', [
'to' => $deviceToken,
'title' => 'Новое сообщение',
'body' => 'У вас 1 новое сообщение',
'data' => ['type' => 'chat', 'chatId' => 5],
]);
Deep link из уведомления
responseSub = Notifications.addNotificationResponseReceivedListener((response) => {
const url = response.notification.request.content.data.url;
if (url) Linking.openURL(url);
});
Отладка
В Expo Go push не работают с реальным сервером. Нужен dev build или production build.
Итоги
expo-notifications- Разрешение обязательно
getExpoPushTokenAsyncдля токена- Каналы на Android
- Слушатели для получения и нажатия
- Локальные через
scheduleNotificationAsync - Сервер шлёт через Expo Push API