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();
}, []);
}