Kurs React Native · Moduł 7: Powiadomienia

Push Notifications

2 min czytania ·
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. 1. Jaki format ma Expo Push Token?

  2. 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.

Przydatne artykuły