> This page is part of the [Customer.io documentation](https://docs.customer.io). For the complete index, see [llms.txt](https://docs.customer.io/llms.txt).
> Last updated: November 13, 2026
> To take actions in Customer.io from an agent, use the [Customer.io CLI](https://docs.customer.io/ai/cli/get-started.md) or the [MCP server](https://docs.customer.io/ai/mcp/get-started.md).

# Silent push

A silent push wakes your app in the background and hands it the data set on the message, without showing anything to the person. Use this page to set your app up to receive silent pushes.

## How it works

When you send a [silent push](https://docs.customer.io/messaging/channels/push/silent-push/), the device wakes your app in the background. The SDK reports *Delivered* to Customer.io and hands your JavaScript handler the key/value data set on the message. A silent push never shows anything, so the SDK never reports *Opened*.

Silent push needs `customerio-expo-plugin` 4.5.0 or later and `customerio-reactnative` 7.3.0 or later. On iOS, it also needs Expo SDK 53 or later.

## Set up silent push

1.  Add the **Remote notifications** background mode to your app config. Without it, iOS doesn’t wake your app for a silent push.

    ```
    {
      "expo": {
        "ios": {
          "infoPlist": {
            "UIBackgroundModes": ["remote-notification"]
          }
        }
      }
    }
    ```

2.  Set the handler in your entry file. On Android, a silent push that starts your app in the background runs your entry file without mounting your app, so a handler you set inside a component would miss it. If you use Expo Router, add an `index.js` file and point `main` in your `package.json` at it:

    ```
    // index.js
    import 'expo-router/entry';
    import { CustomerIO } from 'customerio-reactnative';

    CustomerIO.pushMessaging.setBackgroundPushHandler(async ({ deliveryId, data }) => {
      // data holds the keys and values set on the message.
      // Key your work on deliveryId: the same push can arrive more than once.
      await refreshInbox(data);
    });
    ```

On iOS, the plugin passes silent pushes from your generated `AppDelegate` to the Customer.io SDK. The SDK reports *Delivered* for each silent push and hands it to your handler once your JavaScript sets one. Every other push goes to Expo and your other libraries as before. Android doesn’t need anything from the plugin.

The handler works the same way as in the React Native SDK. See [React Native silent push](https://docs.customer.io/integrations/sdk/react-native/push-notifications/silent-push/#with-the-customer-io-sdk) for how the handler runs on each platform, and how to stop it.

## Use React Native Firebase

If your app uses React Native Firebase, handle silent pushes in one place. React Native Firebase’s handlers see silent pushes either way.

*   To handle them with `setBackgroundPushHandler`, set `android.setHighPriorityPushHandler` to `true` in your plugin config, so Customer.io’s Firebase service gets each FCM message.
*   To handle them in React Native Firebase, leave `android.setHighPriorityPushHandler` unset and don’t call `setBackgroundPushHandler`. See [React Native silent push](https://docs.customer.io/integrations/sdk/react-native/push-notifications/silent-push/#with-react-native-firebase) for the code.

## What to plan for

Silent pushes reach an Expo app under the same limits as a React Native app. See [what to plan for](https://docs.customer.io/integrations/sdk/react-native/push-notifications/silent-push/#what-to-plan-for) in React Native silent push.
