Kurs React Native · Moduł 7: Powiadomienia
Push Notifications
W tej lekcji4
Push notifications są wysyłane z serwera do urządzenia użytkownika.
Expo Push Service
// Na serwerze (Node.js)
import { Expo, ExpoPushMessage } from 'expo-server-sdk';
const expo = new Expo();
async function sendPushNotification(pushToken: string, title: string, body: string) {
const message: ExpoPushMessage = {
to: pushToken,
sound: 'default',
title,
body,
data: { someData: 'goes here' },
};
const chunks = expo.chunkPushNotifications([message]);
const tickets = [];
for (const chunk of chunks) {
const ticketChunk = await expo.sendPushNotificationsAsync(chunk);
tickets.push(...ticketChunk);
}
return tickets;
}Wysyłanie z curl (testowanie)
curl -H "Content-Type: application/json" -X POST \
"https://exp.host/--/api/v2/push/send" \
-d '{
"to": "ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]",
"title":"Wiadomość z Atlantydy",
"body": "Posejdon cię wzywa!"
}'Przechowywanie tokenu na serwerze
// W aplikacji - po rejestracji użytkownika
async function savePushToken() {
const token = await registerForPushNotificationsAsync();
if (token) {
// Wyślij token na swój serwer
await fetch('https://api.atlantyda.app/users/push-token', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
token: token.data,
platform: Platform.OS,
}),
});
}
}Obsługa otrzymanych powiadomień
import { useEffect, useRef } from 'react';
import * as Notifications from 'expo-notifications';
function useNotifications() {
const notificationListener = useRef<Notifications.Subscription>();
const responseListener = useRef<Notifications.Subscription>();
useEffect(() => {
// Listener na otrzymane powiadomienie (app w foreground)
notificationListener.current = Notifications.addNotificationReceivedListener(
(notification) => {
console.log('Otrzymano:', notification);
}
);
// Listener na interakcję z powiadomieniem
responseListener.current = Notifications.addNotificationResponseReceivedListener(
(response) => {
const data = response.notification.request.content.data;
console.log('Kliknięto powiadomienie:', data);
// Nawigacja na podstawie data
if (data.screen) {
navigation.navigate(data.screen, data);
}
}
);
return () => {
notificationListener.current?.remove();
responseListener.current?.remove();
};
}, []);
}Push notifications pozwalają na komunikację z użytkownikiem nawet gdy app jest zamknięta!
Kod do tej lekcji: App.tsx
import { useEffect, useRef, useState } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import * as Notifications from 'expo-notifications';
// Hook obsługujący odbiór i kliknięcie powiadomienia
function useNotifications() {
const [lastNotification, setLastNotification] = useState<string>('');
const notificationListener = useRef<Notifications.Subscription>();
const responseListener = useRef<Notifications.Subscription>();
useEffect(() => {
// TODO: listener na odebrane powiadomienie (app w foreground)
// użyj Notifications.addNotificationReceivedListener
notificationListener.current = Notifications.addNotificationReceivedListener(
(notification) => {
// TODO: zapisz tytuł powiadomienia do stanu
setLastNotification('');
}
);
// TODO: listener na kliknięcie/interakcję z powiadomieniem
// użyj Notifications.addNotificationResponseReceivedListener
responseListener.current = Notifications.addNotificationResponseReceivedListener(
(response) => {
const data = response.notification.request.content.data;
console.log('Kliknięto:', data);
}
);
// TODO: posprzątaj subskrypcje w funkcji czyszczącej (remove())
return () => {
notificationListener.current?.remove();
responseListener.current?.remove();
};
}, []);
return { lastNotification };
}
export default function App() {
const { lastNotification } = useNotifications();
return (
<View style={styles.container}>
<Text style={styles.title}>Push Notifications</Text>
<Text style={styles.info}>Ostatnie: {lastNotification || 'brak'}</Text>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#1a5276' },
title: { fontSize: 24, color: '#fff', marginBottom: 12 },
info: { fontSize: 14, color: '#aed6f1' },
});
Hasła z dokumentacji w tej lekcji
Widzisz błąd w tej lekcji?
Sprawdź się
Odpowiedz na pytania z tej lekcji. Wybierz odpowiedź, a od razu zobaczysz, czy jest poprawna.
1. Jaki format ma Expo Push Token?
2. Pod jaki URL wysyłamy push przez Expo?
To 2 z 4 pytań do tej lekcji. Pozostałe rozwiążesz w grze.
Zadania praktyczne w grze
- Układanie w pionie
Uporządkuj payload push notification:
- Edytor kodu
Uzupełnij kod z listenerami.