Lompat ke konten utama
Mobile Panduan

Panduan Lengkap Expo Push Notification 2026

Kuasai setup Expo push notification. Panduan ini membahas izin, token, pengiriman, penanganan, dan praktik terbaik produksi untuk pengiriman yang andal.

Panduan Lengkap Expo Push Notification 2026

Anda mungkin sudah di tahap aplikasi berjalan, user sudah login, dan tim produk ingin flow re-engagement yang terasa native. Pengingat keranjang. Prompt review. Alert pesan baru. Pengumuman rilis. Insting pertama biasanya adalah "pasang push saja", lalu seminggu kemudian Anda sibuk debugging kenapa satu device dapat alert, simulator terlihat terdaftar dengan baik, tapi tidak ada yang tahu kenapa tap tidak membuka screen yang benar.

Di sinilah Expo push notifications bisa terasa sangat simpel atau justru sangat rapuh.

Expo memberikan layer praktis bagi tim React Native di atas APNs dan FCM, itulah alasan mengapa banyak tim menggunakannya. Namun, celah antara demo dan implementasi siap produksi itu nyata. Lifecycle token, timing permission, setup listener, desain payload, dan backend cleanup semuanya penting. Jika Anda juga sering melakukan perubahan logika app, disiplin operasional menjadi semakin krusial, terutama jika upaya retensi Anda bergantung pada messaging yang andal dan kecepatan rilis. Delivery hanya berguna jika user experience di sekitarnya dapat diprediksi.

Table of Contents

Fondasi untuk Engagement User dengan Expo Push Notifications

Sebuah Push notification Expo setup sangat menarik karena satu alasan utama. Ini menghilangkan banyak kompleksitas native messaging yang tidak ingin ditangani tim di awal. Alih-alih membangun infrastruktur APNs dan FCM secara langsung, Anda bisa menggunakan gateway Expo dan fokus pada perilaku produk, routing, UX permission, serta logika pesan backend.

Abstraksi tersebut tidak membuat push menjadi "kurang nyata." Ini hanya mengubah ke mana upaya engineering Anda dialokasikan.

Layanannya juga cukup cepat sehingga performa biasanya bukan hal pertama yang perlu dikhawatirkan. Dari 14 Maret 2023 hingga 12 Juni 2023, API push notification Expo menunjukkan median response time 42 milidetik, latency p99 sebesar 273 milidetik, dan rata-rata error rate harian 0,17% di seluruh puluhan juta pesan harian, according to analisis benchmark API push Expo dari Knock. Hal ini seharusnya meyakinkan tim mana pun yang ragu apakah Expo hanya cocok untuk prototipe.

Apa yang sebenarnya diabstraksi oleh Expo

Saat tim menyebut “Expo push,” mereka sering kali merujuk pada beberapa hal berbeda yang digabung menjadi satu:

  • Routing provider: Expo meneruskan pesan ke APNs untuk iOS dan FCM untuk Android.
  • Format token: Server Anda menyimpan dan mengirim Expo Push Token alih-alih harus mengelola penanganan token spesifik platform terlebih dahulu.
  • Kontrak request: Anda melakukan POST payload ke API Expo, alih-alih mengintegrasikan API provider native secara langsung.

Hal ini memang membantu, tapi juga memicu kesalahpahaman umum. Tim sering menganggap Expo bertanggung jawab atas semua masalah pengiriman. Padahal, banyak kegagalan disebabkan oleh code app, token yang kedaluwarsa, payload yang salah format, atau alur izin yang buruk.

Aturan praktis: Anggap Expo sebagai layer transport yang andal, bukan pengganti desain client dan backend yang matang.

Apa arti sebenarnya dari kesiapan produksi

Demo yang berjalan hanya membuktikan satu perangkat menerima satu payload sekali saja. Kesiapan produksi berarti hal lain:

Kekhawatiran Mindset Demo Mindset Produksi
Izin Tanya sekarang Bertanya sesuai konteks, setelah nilai produk terasa jelas
Token Simpan sekali Refresh, deduplikasi, kedaluwarsa, dan rekonsiliasi
Payload Masukkan semuanya data Jaga payload tetap kecil dan berorientasi aksi
Perilaku aplikasi Tampilkan alert Navigasi dengan benar dan tangani state foreground
Operasi Tes manual Receipt, cleanup, logs, dan penanganan insiden

Itulah perbedaan antara sekadar “mengirim notifikasi” dan “notifikasi yang mendukung workflow produk nyata.”

Setup Proyek Awal dan Konfigurasi

Banyak kendala Expo push dimulai bahkan sebelum prompt izin pertama muncul. Jika konfigurasi proyek berantakan, code client mungkin terlihat benar, padahal aplikasi masih berperilaku tidak konsisten di berbagai build.

Laptop modern di atas meja kayu yang menampilkan file konfigurasi code untuk setup proyek.

Mulailah dengan library yang tepat dan environment development yang sesuai dengan jalur build Anda. Jika Anda bekerja di luar Expo Go, akan sangat membantu jika menyelaraskan workflow rilis Anda dengan panduan alternatif Expo EAS dari Capgo, karena perilaku notifikasi sering kali perlu divalidasi dalam build yang lebih menyerupai kondisi produksi daripada sekadar menjalankan sandbox secara cepat.

Install package notifikasi

Minimal, Anda biasanya akan membutuhkan:

  • expo-notifications untuk permintaan izin, pengambilan token, listener, dan tampilan notifikasi.
  • expo-device karena Anda harus mengamankan pengambilan token dengan Device.isDevice.

Perintah install biasanya tergantung pada package manager Anda, tetapi kuncinya adalah penyelarasan versi dengan Expo SDK Anda. Jangan mencampur versi package sembarangan. Biarkan Expo yang menentukan versi yang kompatibel.

Tambahkan konfigurasi level proyek

Buat konfigurasi Anda eksplisit. Sebuah app.json atau app.config.js harus mencerminkan bahwa notifikasi adalah bagian dari kontrak aplikasi, bukan sekadar tambahan.

{
  "expo": {
    "name": "MyApp",
    "slug": "my-app",
    "plugins": ["expo-notifications"],
    "ios": {
      "bundleIdentifier": "com.example.myapp"
    },
    "android": {
      "package": "com.example.myapp"
    },
    "extra": {
      "eas": {
        "projectId": "your-project-id"
      }
    }
  }
}

Beberapa detail penting di sini:

  • Bundle identifier dan nama package harus sesuai dengan aplikasi yang Anda rilis.
  • Plugin notifikasi memastikan proyek native mendapatkan setup yang diperlukan saat build.
  • EAS project ID hal ini penting saat pengambilan token mengharuskan aplikasi terhubung dengan proyek Expo yang benar.

Atur notification handler sejak awal

Banyak tutorial dasar terlalu lama mendefinisikan perilaku notifikasi. Jangan lakukan itu. Letakkan di dekat startup aplikasi agar perilaku foreground lebih terprediksi.

import * as Notifications from 'expo-notifications';

Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: false,
    shouldSetBadge: true,
  }),
});

Tim harus memutuskan apakah notifikasi foreground harus menampilkan alert, memutar suara, atau memengaruhi badge. Perilaku pastinya tergantung produk Anda. Aplikasi chat dan aplikasi pembayaran tidak akan mengambil keputusan yang sama.

If you don’t define foreground behavior intentionally, your team will end up debugging “missing” notifications that were actually received but never presented the way product expected.

Android butuh konfigurasi channel

Android notification channels bukan pilihan opsional dalam praktiknya. Jika Anda melewatkannya, alert Anda bisa terlihat tidak konsisten atau gagal memenuhi ekspektasi pengguna.

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

export async function configureAndroidNotifications() {
  if (Platform.OS !== 'android') return;

  await Notifications.setNotificationChannelAsync('default', {
    name: 'Default',
    importance: Notifications.AndroidImportance.MAX,
  });
}

Siapkan ini saat inisialisasi aplikasi. Lalu jaga agar channel ID tetap stabil. Mengubahnya sembarangan akan membuat perilaku notifikasi sulit dipahami nantinya.

Meminta Izin dan Mengambil Push Token

Ini adalah bagian yang sering disalin tim dari snippet, lalu akhirnya mereka menyesal.

Permintaan izin butuh timing, kesadaran platform, dan penanganan async yang disiplin. Pengambilan token hanya boleh dilakukan di perangkat fisik, setelah izin disetujui, dan hanya jika Anda siap menyimpan hasilnya ke backend segera.

Diagram langkah demi langkah yang menunjukkan proses mendapatkan dan menyimpan token Expo push notification.

Fungsi client yang harus menjadi baseline Anda

Gunakan fungsi seperti ini sebagai titik awal Anda:

import * as Device from 'expo-device';
import * as Notifications from 'expo-notifications';
import Constants from 'expo-constants';
import { Platform } from 'react-native';

type RegisterResult =
  | { ok: true; token: string }
  | { ok: false; reason: string };

export async function registerForExpoPushNotificationsAsync(): Promise<RegisterResult> {
  if (!Device.isDevice) {
    return { ok: false, reason: 'Push notifications require a physical device.' };
  }

  if (Platform.OS === 'android') {
    await Notifications.setNotificationChannelAsync('default', {
      name: 'Default',
      importance: Notifications.AndroidImportance.MAX,
    });
  }

  const permissions = await Notifications.getPermissionsAsync();
  let finalStatus = permissions.status;

  if (finalStatus !== 'granted') {
    const request = await Notifications.requestPermissionsAsync();
    finalStatus = request.status;
  }

  if (finalStatus !== 'granted') {
    return { ok: false, reason: 'Notification permission was not granted.' };
  }

  const projectId =
    Constants.expoConfig?.extra?.eas?.projectId ??
    Constants.easConfig?.projectId;

  if (!projectId) {
    return { ok: false, reason: 'Missing EAS project ID configuration.' };
  }

  const tokenResponse = await Notifications.getExpoPushTokenAsync({ projectId });

  return { ok: true, token: tokenResponse.data };
}

Urutannya sangat penting. Cek tipe perangkat dulu, atur perilaku channel Android, selesaikan izin, validasi konfigurasi proyek, baru kemudian minta token Expo.

Mengapa Device.isDevice tidak bersifat opsional

Ini adalah salah satu kesalahan kecil yang menimbulkan banyak masalah meski terlihat sepele. Tim ahli hanya meminta izin secara kondisional saat Device.isDevice bernilai true, dan kesalahan umum yang sering terjadi adalah melewatkan guard tersebut. Hal ini membuat developer mengirim notifikasi ke token simulator yang tidak valid dan menyalahkan Expo, padahal masalah sebenarnya ada pada konfigurasi aplikasi, seperti dijelaskan dalam catatan implementasi notifikasi Expo dari Eagerworks.

Itulah sebabnya pengecekan diletakkan di bagian atas fungsi. Jangan sembunyikan di balik helper. Buatlah prosesnya terlihat jelas.

Hasil simulator berguna untuk testing UI. Namun, simulator tidak bisa diandalkan untuk memvalidasi registrasi push token.

Minta izin di momen yang tepat

Jangan minta izin saat splash screen. Jangan minta sebelum user paham manfaatnya. Waktu terbaik biasanya setelah user melakukan aksi yang membuat manfaat notifikasi terasa nyata, seperti mengaktifkan update pengiriman, bergabung dalam percakapan, atau menyimpan item yang dipantau.

Implementasi yang baik biasanya mengikuti alur ini:

  1. User mencapai batasan fitur yang penting.
  2. App menjelaskan nilai notifikasi melalui UI Anda sendiri.
  3. App meminta izin sistem.
  4. App langsung menyimpan token ke backend jika izin diberikan.

Langkah terakhir inilah yang sering gagal di banyak app. Mereka mengambil token, mencatatnya secara lokal, lalu menunda registrasi backend. Akibatnya, tim support tidak bisa melacak device mana yang memegang token tertentu pada waktu tertentu.

Berikut contoh sederhana cara menyimpan token setelah registrasi:

export async function enablePushForCurrentUser(userId: string) {
  const result = await registerForExpoPushNotificationsAsync();

  if (!result.ok) {
    return result;
  }

  await fetch('https://api.example.com/push-tokens', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: 'Bearer user-session-token',
    },
    body: JSON.stringify({
      userId,
      token: result.token,
      platform: Platform.OS,
    }),
  });

  return result;
}

Nantinya dalam alur kerja ini, panduan ini akan menjadi referensi visual yang berguna:

Bagi tim yang sering merilis update app, anggaplah registrasi token sebagai bagian dari operational state app, bukan sekadar bagian dari onboarding. Pola pikir ini sangat cocok dengan alur kerja pengiriman app Expo, di mana perilaku app bisa sering berubah dan state backend harus tetap sinkron.

Mengirim Notifikasi dari Server Anda

Setelah backend Anda memiliki Expo Push Token yang valid, mengirim notifikasi jadi sangat mudah. Bagian tersulit bukanlah request-nya, melainkan menentukan isi payload dan seberapa besar Anda mempercayai client state.

Berikut contoh minimal gaya Node menggunakan fetch:

type ExpoPushMessage = {
  to: string;
  title: string;
  body: string;
  sound?: 'default' | null;
  data?: Record<string, unknown>;
};

export async function sendExpoPushNotification(token: string) {
  const message: ExpoPushMessage = {
    to: token,
    title: 'New review received',
    body: 'Tap to open the order details.',
    sound: 'default',
    data: {
      type: 'new_review',
      orderId: 'ord_123',
      screen: 'OrderDetails',
    },
  };

  const response = await fetch('https://exp.host/--/api/v2/push/send', {
    method: 'POST',
    headers: {
      Accept: 'application/json',
      'Accept-encoding': 'gzip, deflate',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(message),
  });

  const result = await response.json();
  return result;
}

Fungsi setiap field payload

Jangan jadikan payload tempat pembuangan data. Pastikan setiap field memiliki tujuan.

Field Kegunaan Saran praktis
to Target Token Push Expo Validasi bahwa token milik record perangkat saat ini
title Heading notifikasi Buat singkat dan mudah dibaca
body Teks utama yang terlihat Buat aksi menjadi jelas
sound Perilaku suara sistem Gunakan secukupnya untuk alert penting
data Metadata khusus aplikasi Utamakan ID dan petunjuk rute daripada konten berat

Skill data object adalah tempat workflow produk menjadi berguna. Anda bisa mengirimkan tipe dan ID record, lalu biarkan aplikasi mengambil data terbaru saat user mengetuknya. Ini lebih aman daripada menyisipkan blob besar atau sensitif langsung di dalam payload.

Jaga payload tetap kecil dan sederhana

According to panduan Courier untuk notifikasi Expo, Expo Push Tokens harus dianggap bersifat sementara; payload yang melebihi batas ukuran sekitar 4 KB bisa terbuang, dan pola yang andal adalah mengirim payload metadata kecil seperti { "type": "new_review", "id": 123 } daripada menggunakan JSON besar atau media inline. Saran ini sesuai dengan praktik sistem nyata. Payload kecil lebih jarang gagal dan lebih stabil saat logika aplikasi berubah.

Kirim data secukupnya untuk mengarahkan user. Ambil sisanya setelah aplikasi terbuka.

Kebiasaan server-side yang berguna

Fungsi send dasar sudah cukup untuk testing. Untuk produksi, biasanya perlu tambahan tanggung jawab berikut:

  • Simpan riwayat percobaan pengiriman: Simpan intent notifikasi beserta user ID, token, tipe payload, dan timestamp.
  • Pisahkan pembuatan konten dari transport: Buat copy pesan di satu layer dan request Expo API di layer lainnya.
  • Tangani feedback invalidasi: Jika Expo kemudian melaporkan DeviceNotRegistered, mark that token stale and stop retrying blindly.
  • Gunakan desain yang ramah webhook: Jika sistem Anda sudah memancarkan event, arahkan trigger notifikasi melalui pola pemrosesan backend webhook yang sama yang Anda gunakan di tempat lain.

Sebelum men-debug client listener, kirim test push manual terlebih dahulu. Jika token menerima notifikasi biasa dengan payload kecil, jalur transport Anda kemungkinan besar aman. Jika tidak, jangan mulai dengan mengubah navigasi code. Mulailah dengan memvalidasi token, bentuk payload, dan status permission.

Menangani Notifikasi Masuk di Aplikasi Anda

Pengiriman hanyalah setengah dari fitur ini. Aplikasi harus melakukan sesuatu yang koheren saat notifikasi tiba dan saat pengguna mengetuknya.

Itu berarti menangani dua momen terpisah:

  • notifikasi tiba saat aplikasi sedang terbuka
  • pengguna berinteraksi dengan notifikasi dari system tray atau lock screen

Diagram flowchart yang mengilustrasikan lifecycle push notification untuk aplikasi mobile dalam status foreground dan background.

Penerimaan di foreground dan respons pengguna adalah event yang berbeda

Setup yang andal biasanya menyertakan kedua listener ini:

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

export function useNotificationObservers(
  onForegroundMessage: (notification: Notifications.Notification) => void,
  onNotificationTap: (response: Notifications.NotificationResponse) => void
) {
  useEffect(() => {
    const receivedSub = Notifications.addNotificationReceivedListener(
      (notification) => {
        onForegroundMessage(notification);
      }
    );

    const responseSub = Notifications.addNotificationResponseReceivedListener(
      (response) => {
        onNotificationTap(response);
      }
    );

    return () => {
      receivedSub.remove();
      responseSub.remove();
    };
  }, [onForegroundMessage, onNotificationTap]);
}

addNotificationReceivedListener berjalan saat aplikasi sedang aktif. addNotificationResponseReceivedListener berjalan saat user mengetuk notifikasi yang masuk. Jangan disamakan, karena keduanya memiliki alur UX yang berbeda.

Baca data payload dan navigasi secara terarah

Berikut adalah pola praktis untuk menangani tap:

type NotificationData = {
  type?: string;
  orderId?: string;
  screen?: string;
};

export function handleNotificationTap(
  response: Notifications.NotificationResponse,
  navigation: any
) {
  const data =
    response.notification.request.content.data as NotificationData;

  if (data.screen === 'OrderDetails' && data.orderId) {
    navigation.navigate('OrderDetails', { orderId: data.orderId });
    return;
  }

  if (data.type === 'new_review') {
    navigation.navigate('Inbox');
    return;
  }

  navigation.navigate('Home');
}

Pola ini tetap tangguh karena payload hanya berisi petunjuk routing, bukan seluruh dokumen. Jika urutan data berubah sejak notifikasi dikirim, aplikasi dapat mengambil state server terbaru setelah navigasi.

Notifikasi yang diketuk harus mengarah ke satu tujuan yang jelas. Jika fallback path Anda tidak jelas, user akan langsung menyadarinya.

Perilaku foreground harus sesuai dengan konteks user

Saat aplikasi sudah terbuka, menampilkan alert bergaya sistem secara sembarangan bisa terasa canggung. Terkadang langkah yang lebih tepat adalah banner in-app, update badge, atau silent refresh. Layar inbox support mungkin tidak butuh alert visual jika user sedang membaca percakapan tersebut.

Itulah sebabnya foreground listener Anda harus bercabang berdasarkan route dan tipe notifikasi. Contohnya:

  • Layar Chat terbuka: tambahkan pesan tersebut dan hindari banner yang redundan
  • Dashboard terbuka: tampilkan toast in-app yang ringan
  • Event akun kritis: gunakan UI treatment yang lebih kuat

Pendekatan sederhananya seperti ini:

export function handleForegroundNotification(
  notification: Notifications.Notification,
  currentRouteName: string
) {
  const data = notification.request.content.data as { type?: string };

  if (currentRouteName === 'ChatThread' && data.type === 'new_message') {
    // refresh local thread state
    return;
  }

  // otherwise show your own in-app UI or update badges
}

Jika aplikasi Anda tidak membedakan konteks ini, pengguna akan lebih cepat merasa jenuh dengan notifikasi, meskipun pengirimannya secara teknis sudah benar.

Best Practices Produksi dan Kesalahan Umum

Kebanyakan setup Expo push notification yang bermasalah bukan karena Expo terlalu terbatas. Masalah muncul karena tim berasumsi token bersifat permanen, payload bisa berisi apa saja, dan update aplikasi tidak akan memengaruhi logika notifikasi.

Asumsi tersebut tidak akan bertahan di lingkungan produksi.

Infografis checklist yang merangkum delapan best practices untuk mengelola push notification produksi pada aplikasi mobile.

Token bersifat ephemeral, bukan catatan identitas

Expo Push Token sebaiknya diperlakukan seperti sewa, bukan pengenal perangkat seumur hidup. Token bisa berubah setelah instal ulang, perubahan OS, atau event lifecycle lainnya. Jika sebuah token akhirnya muncul kembali DeviceNotRegistered, backend Anda harus berhenti menganggapnya aktif.

Model backend praktis menyimpan:

  • ID pengguna
  • platform
  • metadata per instalasi
  • token saat ini
  • timestamp terakhir terlihat
  • status seperti active, stale, atau revoked

Jangan cuma simpan satu field token di tabel user lalu selesai. User punya banyak device, dan status device bisa berubah.

Strategi refresh lebih penting daripada yang diakui kebanyakan tutorial

Panduan resmi ekosistem menyisakan celah operasional nyata di sini. Konten push notification Expo yang ada sering kali tidak menjelaskan cara menjaga validitas token di tengah siklus review App Store dan update OTA, yang sangat penting bagi tim yang sering merilis perubahan live karena reliabilitas push bergantung pada status token saat ini dan sinkronisasi backend, seperti yang disebutkan dalam Dokumentasi notifikasi Expo.

Hal ini memengaruhi cara Anda merancang trigger refresh. Waktu yang tepat untuk menyelaraskan status token antara lain:

  • Peluncuran aplikasi setelah update
  • Login pengguna
  • Perubahan pengaturan izin
  • Rotasi kredensial pada proses rilis Anda
  • Alur pemulihan setelah tiket support terkait push

Keamanan dan kepatuhan tidak seharusnya ditaruh di akhir sprint

Banyak tutorial Expo fokus pada mekanik dan melewatkan risiko operasional. Itu wajar untuk aplikasi hobi. Tapi tidak untuk produk yang bersinggungan dengan kesehatan, fintech, atau commerce yang teregulasi.

Diskusi Courier yang berfokus pada enterprise mengenai celah notifikasi Expo menyoroti kurangnya panduan praktis terkait pencatatan persetujuan (consent logging), jejak audit, dan cara meminimalkan paparan payload sensitif. Pelajaran teknis utamanya sederhana:

  • Jangan masukkan data bisnis sensitif ke dalam teks notifikasi atau metadata payload.
  • Log perubahan consent di sisi server.
  • Catat intent notifikasi mana yang dikirim ke token mana.
  • Gunakan ID dalam payload dan ambil konten terproteksi setelah aplikasi dibuka.

Untuk tim yang menyelaraskan operasional rilis dengan kepatuhan app store dan praktik keamanan API, push harus disertakan dalam disiplin review yang sama dengan auth, analytics, dan backend event logging.

Push notification adalah pesan untuk user, tapi ini juga masalah distributed systems. Tangani dengan ketelitian yang sama seperti auth state dan payment events.

Apa yang biasanya berhasil dan apa yang biasanya error

Biasanya berhasil Biasanya error
Meminta izin setelah penjelasan value yang jelas Memunculkan prompt pada frame pertama
Testing di perangkat asli Percaya pada registrasi simulator
Simpan token dengan konteks perangkat Satu token per record user
Kirim payload metadata kecil Menyisipkan blob besar atau sensitif
Pisahkan handling event foreground dan tap Menganggap semua notifikasi lewat satu jalur
Menghapus token usang secara agresif Retry token mati terus-menerus

Setup Expo push yang solid itu tidak rumit. Tapi butuh disiplin.


Jika tim Anda sering merilis perubahan logika app dan butuh kontrol lebih ketat atas perilaku rilis, rollback, serta visibilitas pengiriman, Capgo patut dicoba. Ini membantu tim mobile melakukan push update dengan cepat tanpa menunggu review store, yang sangat berguna saat alur notifikasi, logika routing, atau perbaikan client-side perlu segera sampai ke pengguna.

Live update untuk aplikasi Capacitor

Saat bug di web layer sudah live, kirim perbaikannya lewat Capgo alih-alih menunggu berhari-hari untuk persetujuan app store. Pengguna menerima update di background, sementara perubahan native tetap di jalur review normal.

Terbaru dari Blog kami

Capgo memberikan insight terbaik yang Anda butuhkan untuk membuat aplikasi mobile yang benar-benar profesional.