React Native Academy · บทเรียน

การจัดการการแจ้งเตือนขณะอยู่เบื้องหน้าและเบื้องหลัง

ใช้ addNotificationReceivedListener เพื่อจัดการการแจ้งเตือนขณะที่แอปเปิดอยู่ และใช้ addNotificationResponseReceivedListener เพื่อตอบสนองเมื่อผู้ใช้แตะการแจ้งเตือน

บทเรียน 3 จาก 413 ขั้นตอน

การจัดการการแจ้งเตือนขณะอยู่เบื้องหน้าและเบื้องหลัง เป็นบทเรียน React Native Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน React Native Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส React Native Academy มีบทเรียนทั้งหมด 4 บทเรียน

บางส่วนของบทเรียนนี้ยังไม่ได้รับการแปล และแสดงเป็นภาษาอังกฤษ

App States and Notification Delivery

Your app can be in three states when a notification arrives: foreground (app is open and visible), background (app is running but not visible), or killed (app is not running at all). Each state has different handling requirements and different APIs to use.

Understanding which state applies is critical because the OS delivers notifications differently in each case and the user's tap response routes through different code paths depending on the app state at the time they tap.

addNotificationReceivedListener

Notifications.addNotificationReceivedListener fires when a notification arrives while the app is in the foreground. By default, notifications do not show a banner or sound when the app is already open — you must handle them in-app. The listener receives the full notification object including all content and data payload.

Use this to show in-app banners, update UI (e.g., refresh a chat thread), or play a custom sound — giving users the same experience as if the notification had arrived while the app was in the background.

import * as Notifications from 'expo-notifications';
import { useEffect } from 'react';

useEffect(() => {
  const subscription = Notifications.addNotificationReceivedListener(
    (notification) => {
      const { title, body, data } = notification.request.content;
      console.log('Notification received in foreground:', title, body);
      // Update UI or show in-app banner:
      showInAppBanner({ title, body });
    }
  );

  return () => subscription.remove();
}, []);

addNotificationResponseReceivedListener

Notifications.addNotificationResponseReceivedListener fires when the user taps a notification, regardless of whether the app was in the background or killed. The listener receives a response object that contains the notification, the action identifier (which button was tapped), and any user text input.

Use this to navigate to the relevant screen based on the notification's data payload. This is the most important notification handler because it drives the deep navigation behavior users expect when tapping a notification.

useEffect(() => {
  const subscription = Notifications.addNotificationResponseReceivedListener(
    (response) => {
      const { data } = response.notification.request.content;
      console.log('User tapped notification:', data);

      if (data.screen) {
        navigation.navigate(data.screen, { id: data.id });
      }
    }
  );

  return () => subscription.remove();
}, []);

Notification Data Payload Design

The data field in a push notification is your app's contract with itself — it determines what happens when the notification is tapped. Design a consistent schema that includes the destination screen name and all parameters that screen needs.

A well-designed data payload allows any notification to navigate to precisely the right screen with the right content without any guessing. Use type-safe constants for action types to prevent typos causing silent navigation failures.

// Consistent data payload schema:
const notificationData = {
  type: 'new_message',   // action type
  screen: 'Chat',        // destination screen name
  conversationId: 'abc', // screen params
  senderId: '123',
};

// Response handler:
const { type, screen, conversationId } = response.notification.request.content.data;

switch (type) {
  case 'new_message':
    navigation.navigate(screen, { conversationId });
    break;
  case 'order_update':
    navigation.navigate('OrderDetail', { orderId: data.orderId });
    break;
}

Foreground Notification Display Control

By default in expo-notifications, notifications received while the app is in the foreground are silent (no banner, no sound). Control this with the setNotificationHandler set at app startup. The handler function is async — you can even make an API call to decide whether to show a notification based on user preferences.

Return shouldShowAlert: true to show the system banner even when the app is open. This is appropriate for notifications from other users (messages) but often not for your own app's activity notifications.

Notifications.setNotificationHandler({
  handleNotification: async (notification) => {
    const { type } = notification.request.content.data;
    // Show banner for messages but not for own activity:
    return {
      shouldShowAlert: type !== 'own_activity',
      shouldPlaySound: type === 'new_message',
      shouldSetBadge: true,
    };
  },
});

Background Notification Handling on iOS

On iOS, you can configure background notifications (silent push notifications) that wake the app in the background to fetch data without showing a banner. Set content-available: 1 in the APNs payload. The app gets a short window (~30 seconds) to fetch data.

Background fetch is useful for pre-loading content before the user opens the app from a notification, ensuring the screen is ready instantly. Handle it with expo-notifications' background notification tasks using Expo's task manager.

import * as TaskManager from 'expo-task-manager';
import * as Notifications from 'expo-notifications';

const BACKGROUND_NOTIFICATION_TASK = 'background-notification';

TaskManager.defineTask(BACKGROUND_NOTIFICATION_TASK,
  async ({ data: { notification }, error }) => {
    if (error) return;
    // Fetch fresh data silently in the background:
    await prefetchDataForNotification(notification.request.content.data);
  }
);

Notifications.registerTaskAsync(BACKGROUND_NOTIFICATION_TASK);

Notification Action Buttons

Notifications can include action buttons that let users respond without opening the app. For example, a message notification might have 'Reply' and 'Mark Read' buttons. Configure categories with Notifications.setNotificationCategoryAsync and reference the category in your push payload.

The tap response listener's response.actionIdentifier tells you which button was tapped. For text input actions, response.userText contains what the user typed directly from the notification.

// Define notification category with actions:
await Notifications.setNotificationCategoryAsync('message', [
  {
    identifier: 'reply',
    buttonTitle: 'Reply',
    textInput: { submitButtonTitle: 'Send', placeholder: 'Type a reply...' },
  },
  {
    identifier: 'mark_read',
    buttonTitle: 'Mark as Read',
    isDestructive: false,
  },
]);

// In response listener:
if (response.actionIdentifier === 'reply') {
  sendReply(response.userText, messageId);
}

Managing Badge Count

The badge count is the red number on your iOS app icon. Set it by including a badge number in your push payload, or update it from within the app using Notifications.setBadgeCountAsync(count). Reduce the badge when the user reads notifications or visits the relevant screen.

A common pattern: server sets badge to unread count when sending a push, and app calls setBadgeCountAsync(0) when the user opens the inbox. Always fetch the true unread count from your server rather than incrementing a local counter, since multiple devices must stay in sync.

import * as Notifications from 'expo-notifications';

// Clear badge when user opens inbox:
async function clearBadge() {
  await Notifications.setBadgeCountAsync(0);
}

// Get current badge count:
const count = await Notifications.getBadgeCountAsync();
console.log('Current badge:', count);

// Update badge from server-returned unread count:
async function updateBadge(unreadCount) {
  await Notifications.setBadgeCountAsync(unreadCount);
}

Dismissing Displayed Notifications

After reading a notification in-app, you should dismiss the corresponding notification from the notification center so it doesn't mislead the user. Use Notifications.dismissNotificationAsync(identifier) for a specific notification or Notifications.dismissAllNotificationsAsync() to clear all.

Call dismiss in the notification response handler after navigating to the relevant screen, or in useEffect on the target screen when it mounts. The notification identifier is available in the response object.

const subscription = Notifications.addNotificationResponseReceivedListener(
  async (response) => {
    const { data } = response.notification.request.content;
    const notifId = response.notification.request.identifier;

    // Navigate to relevant screen:
    navigation.navigate(data.screen, { id: data.id });

    // Dismiss the notification from notification center:
    await Notifications.dismissNotificationAsync(notifId);
  }
);

Getting All Pending Notifications

Retrieve all currently displayed notifications in the notification center with Notifications.getPresentedNotificationsAsync(). Use this on app launch to handle any notifications the user hasn't tapped yet, or to display an unread count badge based on actual notification center contents.

On app foreground, you can also loop through pending notifications and dismiss ones that are now stale (e.g., expired promotions or events that have passed).

useEffect(() => {
  // When app comes to foreground:
  async function cleanupStaleNotifications() {
    const displayed = await Notifications.getPresentedNotificationsAsync();
    const now = Date.now();

    for (const notif of displayed) {
      const { expiresAt } = notif.request.content.data;
      if (expiresAt && expiresAt < now) {
        await Notifications.dismissNotificationAsync(notif.request.identifier);
      }
    }
  }
  cleanupStaleNotifications();
}, [appState]);

A Complete Notification Handler Setup

A production-ready notification setup combines all the pieces: set the handler at startup, register listeners in a custom hook, and wire them to navigation. The custom hook handles both foreground (show banner, update state) and tap responses (navigate), and always cleans up listeners on unmount.

This architecture keeps notification logic centralized, testable, and separate from individual screen components.

function useNotifications(navigation) {
  useEffect(() => {
    const received = Notifications.addNotificationReceivedListener(
      (notif) => handleForeground(notif)
    );
    const response = Notifications.addNotificationResponseReceivedListener(
      (resp) => handleTap(resp, navigation)
    );
    return () => {
      received.remove();
      response.remove();
    };
  }, [navigation]);
}

// Use in root component:
const navigation = useNavigation();
useNotifications(navigation);

Quick Check

Test your understanding of React Native Mobile Development concepts from this lesson.

Lesson Recap

In this lesson you learned: addNotificationReceivedListener handles notifications arriving while the app is in the foreground, addNotificationResponseReceivedListener handles user taps on notifications from any app state and should navigate to the relevant screen, and action buttons with categories enable users to reply or take actions directly from the notification without opening the app. Next up we configure notification channels and add rich content like images and action buttons.

เริ่มต้นได้ฟรี

เรียนรู้ JavaScript ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
30
บทเรียน
120

คำถามที่พบบ่อย

บทเรียน “การจัดการการแจ้งเตือนขณะอยู่เบื้องหน้าและเบื้องหลัง” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การจัดการการแจ้งเตือนขณะอยู่เบื้องหน้าและเบื้องหลัง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส React Native Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส React Native Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การจัดการการแจ้งเตือนขณะอยู่เบื้องหน้าและเบื้องหลัง”

ใช้ addNotificationReceivedListener เพื่อจัดการการแจ้งเตือนขณะที่แอปเปิดอยู่ และใช้ addNotificationResponseReceivedListener เพื่อตอบสนองเมื่อผู้ใช้แตะการแจ้งเตือน คุณปฏิบัติ React Native Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน React Native Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน React Native Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “การจัดการการแจ้งเตือนขณะอยู่เบื้องหน้าและเบื้องหลัง” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน React Native Academy นี้ได้ไหม

ได้ บทเรียน React Native Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. การขอสิทธิ์และรับโทเค็นพุช
  2. การส่งการแจ้งเตือนผ่าน Expo Push API
  3. การจัดการการแจ้งเตือนขณะอยู่เบื้องหน้าและเบื้องหลัง
  4. ช่องการแจ้งเตือนและเนื้อหาแบบหลากหลาย
← กลับไปที่ React Native Academy