Are silent Expo push-notifications possible?

1.6k views Asked by At

I have a critical requirement for my app where I need to silently process PUSH notifications in both Android and IOS.

I've already made a prototype that receives the notifications, but I didn't find a way to avoid the prompt and the sound.

Is that even possible using Expo? should I use pure react-native instead?

2

There are 2 answers

0
Archimedes Trajano On

One thing to note is in Expo Go the Notifications.setNotification() does not fire when the app is backgrounded. Instead the default notification handler which shows the content appears.

You can send a "silent" notification by removing the title and body from the message being sent to Expo Push Notifications. Then use the data to provide the details for the notifications.

Here is a notification-handler.ts that would add as a side-effect the background notification handler.

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

// This is a custom type as the `data` sent is unknown, so if
// you know what to expect you can utilize TypeScript to provide
// you with a cleaner data mapping.
type MyNotificationData = {
  body: Record<string, string>,
  experienceId: string,
  projectId: string,
}

const BACKGROUND_NOTIFICATION_TASK = "BACKGROUND-NOTIFICATION-TASK";

TaskManager.defineTask(
  BACKGROUND_NOTIFICATION_TASK,
  async ({ data, error, executionInfo }) => {
    const notificationData = data as NotificationData;
    // do your thing

    // make your own notification
    await Notifications.scheduleNotificationAsync({
      content: {
        title: notificationData.body.titleText,
        body: notificationData.body.bodyText
      },
      trigger: null, // show the notification immediately
    });
  },
);

Notifications.registerTaskAsync(BACKGROUND_NOTIFICATION_TASK);

For this to work in iOS you also need to add to the app.json the UIBackgroundModes array with remote-notification e.g. with background fetch support as well

"ios": {
  "infoPlist": {
    "UIBackgroundModes": ["remote-notification", "fetch"]
  }
}

This answer combines information from

In addition for this to work with iOS you need to add _contentAvailable: true to the payload. e.g.

curl -X POST https://exp.host/--/api/v2/push/send -H "Accept: application/json" -H "Content-Type: application/json" \
   -d '{
    "to":"ExponentPushToken[mytoken]",
    "_contentAvailable":true,
    "data":{"testing":123}
   }'
2
oallanmendes On

I needed to send a "silent" notification to update the badge count on our iOS and Android apps. The solution I found is to send a notification throw the "https://expo.dev/notifications" and did not provide "title" and "message" content, only provided the "badge count" info.

Works like a charm for us.