[solved] android receive data from a fcm-push notification in detached app

target: android
“expo”: “^29.0.0”,
“expokit”: “1.5.0”,
type of app: android-standalone-apk detached with exp detach

Currently working:

  • I use FCM (Firebase Cloud Messaging)
  • I can retrieve the firebase-token
  • I can send a notification to the app
  • When the app is closed or in the background, the notification appears
  • when I click on the notification, the app opens or (when in background) comes to the foreground

Not working:
I cannot extract data from the push-notification. I thought I can use the same logic which is in the documentation for expo-push (not fcm-push) which I found here:

But this does not work. When I use the code

componentDidMount() {
    // ... do some things...
    this._notificationSubscription = Notifications.addListener(this._handleNotification);

…then the method _handleNotification is never called

My Question:
Do I miss something? Or is my implementation wrong? How do I get data from a notification when I use FCM-push in a android-detached-app?

Push Notifications don’t work on Detached apps.

You need to use for exemple, One Signal:

Thanks @victorwads - yes I think this was in the past, but the developers from expo did a good job for fcm-push in the last months.

So after many hours with trial and error I can joyfully say that firebase-push-notifications are now fully working on android when I use exp detach :tada: :tada: :tada:.

The important thing is the format of the payload.

difference between debug and production

The key notificationExperienceUrl should be set different in the payload depending on using a debug-build or a production build.

For the example we assume that the scheme of your app is mycooldemoapp
More informations about setting the scheme (before detaching)

We need the specific different treating for the following usecase:

  • app is closed (app was open before)
  • push notification received by the device
  • user taps push-notification
  • app opens

when you don’t respect the different treating, then your app will try to open a second window.

When you are in debug mode

check the url in your running expo-development server
(in our example host=lan, ip= port=19000)

"notificationExperienceUrl": "mycooldemoapp://"

When you are in production mode

"notificationExperienceUrl": "exp://exp.host/@your_community_name/your-expo-project"

old firebase api

In our environment we use the Legacy HTTP protocol documented here:

And now comes the tricky part. Currently (sdk 29) you need to provide your data in multiple places in a json. Yes - thats not crazy - thats really true. The reason is, that expo treats notifications differently on the following use-cases:

  • app is closed
  • app is open and in foreground
  • app is open and in background

to use the following template you have to replace

  • firebase-token
  • @your_community_name/your-expo-project
  "notification": {
    "title": "the real title",
    "body": "the real bodytext"
  "data": {
    "notificationExperienceUrl": "exp://exp.host/@your_community_name/your-expo-project",
    "title": "data.title",
    "message": "data.message",
    "body": {
      "pathInJson": "data.body",
      "key2": "value2 in data.body"
    "experienceId": "@your_community_name/your-expo-project",
    "notificationId": -1,
    "isMultiple": false,
    "remote": true,
    "notification_object": {
      "title": "notification_object.title",
      "experienceId": "@your_community_name/your-expo-project",
      "notificationId": -1,
      "isMultiple": false,
      "remote": true,
      "data": {
        "pathInJson": "data.notification_object.data",
        "key2": "value2 in data.notification_object.data"

new firebase api

Documentation here FCM HTTP v1 API

The new firebase-api

  • encloses all data with the key message
  • works with oauth
  • does not allow deep-level json; so you must provide a string to the keys message.data.body and message.data.notification_object; but the good news is, that the guys from expo where smart enough to extract an escaped Json-string to a json.object, so you can use the following template:
  "message": {
    "token": "FIREBASETOKEN",
    "notification": {
      "title": "the real title",
      "body": "the real bodytext"
    "data": {
      "notificationExperienceUrl": "exp://exp.host/@your_community_name/your-expo-project",
      "title": "data.title",
      "message": "data.message",
      "body": "{\"pathInJson\": \"data.body\", \"key2\": \"value2\"}",
      "experienceId": "@your_community_name/your-expo-project",
      "notificationId": "-1",
      "isMultiple": "false",
      "remote": "true",`Preformatted text`
      "notification_object": "{\"title\": \"notification_object.title\",\r\n\"experienceId\": \"@your_community_name/your-expo-project\",\r\n\"notificationId\": -1,\r\n\"isMultiple\": false,\r\n\"remote\": true,\r\n\"data\": {\"pathInJson\": \"data.notification_object.data\", \"key2\": \"value2\"}}"

steps for android-studio

Before detaching:

  • get google-services.json from firebase console and place it on the top-level of your expo-project
  • in app.json
    • set the keyexpo.android.googleServicesFile to "./google-services.json"
    • set the key expo.scheme to "mycooldemoapp"
  • run exp detach

After detaching

in AndroidManifest.xml

  • comment (disable) the GCM-part
  • keep the FCM-part untouched


  • comment (disable)
    implementation 'com.google.android.gms:play-services-gcm:15.0.1'
  • insert (maybe versions you have to update)
    implementation 'com.google.firebase:firebase-core:16.0.1'
    implementation 'com.google.firebase:firebase-messaging:17.3.0'

in app/src/main/java/host/exp/exponent/generated/AppConstants.java

  • public static boolean FCM_ENABLED = true;

in App.js

  • get your firebase-token with await Notifications.getDevicePushTokenAsync();
  • for reacting on the notifications you can use Notifications.addListener

I think thats all
good luck everybody


This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.