Skip to content

Push Notifications

With SDK

You can track when a user opens a MovableInk Push Notification by calling handlePushNotificationOpened with the notification's payload.

import * as Notifications from 'expo-notifications';
import { useEffect } from 'react';
import RNMovableInk from '@movable/react-native-sdk';

// Configure how notifications are handled when app is in foreground
Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: true,
    shouldSetBadge: false,
  }),
});

// Helper function to extract payload from notification
function extractPayload(request: Notifications.NotificationsRequest) {
  let rawData: Record<string, unknown> = {};

  // iOS: trigger.payload contains the full APNS payload
  if (request.trigger?.payload) {
    rawData = request.trigger.payload;
  }
  // Android: trigger.remoteMessage contains the FCM payload
  else if (request.trigger?.remoteMessage?.data) {
    rawData = request.trigger.remoteMessage.data;
  }

  return rawData;
}

// Notification click/tap handler
function App() {
  useEffect(() => {
    // Handle notification click when app is in foreground or background
    const subscription = Notifications.addNotificationResponseReceivedListener(
      async (response) => {
        const payload = extractPayload(response.notification.request);
        RNMovableInk.handlePushNotificationOpened(payload);
      }
    );

    // Handle notification that opened the app from killed state
    Notifications.getLastNotificationResponseAsync().then((response) => {
      if (response) {
        const payload = extractPayload(response.notification.request);
        RNMovableInk.handlePushNotificationOpened(payload);
      }
    });

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

Without SDK

If you're not using the SDK, you can still track this event by manually making a request to the URL in the payload.

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

// Configure how notifications are handled when app is in foreground
Notifications.setNotificationHandler({
  handleNotification: async () => ({
    shouldShowAlert: true,
    shouldPlaySound: true,
    shouldSetBadge: false,
  }),
});

// Helper function to extract URL from notification content
function extractTrackingUrl(request: Notifications.NotificationsRequest) {
  let rawData: Record<string, unknown> = {};

  // iOS: trigger.payload contains the full APNS payload
  if (request.trigger?.payload) {
    rawData = request.trigger.payload;
  }
  // Android: trigger.remoteMessage contains the FCM payload
  else if (request.trigger?.remoteMessage?.data) {
    rawData = request.trigger.remoteMessage.data;
  }

  if (rawData?.mi?.url) {
    return rawData.mi.url as string;
  } else if (rawData?.mi_url) {
    return rawData.mi_url as string;
  }

  return null;
}

// Notification click/tap handler
function App() {
  useEffect(() => {
    // Handle notification click when app is in foreground or background
    const subscription = Notifications.addNotificationResponseReceivedListener(
      async (response) => {
        const url = extractTrackingUrl(response.notification.request);

        if (url) {
          try {
            await fetch(url);
          } catch (error) {
            // Handle error
          }
        }
      }
    );

    // Handle notification that opened the app from killed state
    Notifications.getLastNotificationResponseAsync().then((response) => {
      if (response) {
        const url = extractTrackingUrl(response.notification.request);

        if (url) {
          fetch(url).catch((error) => {
            // Handle error
          });
        }
      }
    });

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