react-native-fcm: background app - on("notification") not triggered after notification click

Versions: rn - 0.34.1 fcm - 2.3.2

I have an android app. When I click on home button to move the app to background and then sending a notification, the notification goes to notification area, but when I click on the notification, the app goes to foreground directly (it’s not re-launching) and the notification data is not passed to the app. Is this related to the hybrid notification problems? I thought that the hybrid problem is just when not clicking on the notification, but when clicking it should pass the data to the app somehow.

notification payload:

{
        priority: 'normal',
        contentAvailable: true, //for ios
        delayWhileIdle: true,
        timeToLive: fcmConfig.timeToLive,
        restrictedPackageName: 'my app id',
        dryRun: fcmConfig.isDryRun,
        data: {
            myData: {
                id: '123456',
            }
        },
        notification: {
            title: 'Hello world title',
            icon: "ic_launcher",
            body: 'Hello world body',
            sound: 'default',
        },
    }

javascript:


///When app started:
FCM.getInitialNotification()
        .then(notification => {
            if (notification && notification.myData) {
                alert(notification.myData);
            }
        });
FCM.on('notification', (notif) => {
        alert("on: " + notif.myData);
});

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 19

Most upvoted comments

I didn’t need to add an AppState listener whatsoever. To summarize, this is how I’m handling notifications in my app, there’s 3 scenarios:

App isn’t Running:

  • Firebase SDK will display a system notification. Pressing the banner will open the app, and getInitialNotification() will fire. This is a promise that seems to always fire (with an empty notification if there isn’t an initial notification), so you can show a loading screen and wait until this promise resolves to show a screen based on the notification

App is in Foreground:

  • Firebase SDK wont fire a system notification. Instead, the data payload will get passed through FCM.on('notification' event. If you want to show a system notification, here you need to trigger a manual, local notification. Be careful with this, since the local notification will fire FCM.on('notification' itself, and you could have a loop creating infinite notifications.

App is in Background:

  • Firebase SDK will display a system notification. Pressing the banner will open the app with an intent, specified by the click_action. The activity needs to be specified as singleTop and be able to handle that intent. The Activity will show and because it’s already running, FCM.on('notification' event will fire.

Hopefully that’s helpful. That’s been my experience with this package, and I’m running Android Marshmallow. It might be different on other phones.

To be honest with you, I think the right thing todo is to write my own Firebase listening service, use just data notifications, and fire local notifications when those are received. That’s what I’m going to do eventually. Getting all this to work was a big pain, and it’s mostly because of Firebase.

More notes…

  • I didn’t change MainActivity.java
  • using "react-native": "0.33.0", "react-native-fcm": "2.3.0",

Sample payload:

{
  "to" : "token-goes-here",
  "notification" : {
    "title" : "Story title",
    "body" : "location name",
    "icon" : "ic_stat_notify",
    "sound": "default",
    "click_action": "geosocial.story"
  },
  "data" : {
    "title" : "Story title",
    "body" : "location name",
    "icon" : "ic_stat_notify",
    "story_id" : "10279"
  },
}

Relevant parts of AndroidManifest (notice geosocial.story intent)

<application
      android:name=".MainApplication"
      android:allowBackup="true"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher_geosocial"
      android:theme="@style/AppTheme">

      <!-- For displaying local notifications -->
      <receiver android:name="com.evollu.react.fcm.FIRLocalMessagingPublisher"/>

      <!-- For listening to firebase messages -->
      <service android:name="com.evollu.react.fcm.MessagingService">
        <intent-filter>
          <action android:name="com.google.firebase.MESSAGING_EVENT"/>
        </intent-filter>
      </service>

      <!-- For handling rotating firebase ids -->
      <service android:name="com.evollu.react.fcm.InstanceIdService" android:exported="false">
        <intent-filter>
          <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
        </intent-filter>
      </service>

      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:launchMode="singleTop"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <intent-filter>
          <action android:name="geosocial.story" />
          <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
      </activity>
      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
      <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="@string/google_maps_api_key"/>
    </application>

@atlanteh @dslounge @kylebebak Do any of you still use this library? I’m completely mystified. Despite specifying click_action and having the matching intent, no combination of notification and data currently fires off the main callback at all on android, and I have no idea how to even go about debugging it. My app is receiving notifications in the background, but opening it from tray never, ever gets recognized.

i got a solution for that. just put below code in oncreate method of launcher activity.

if (bundle != null) {
        String value = bundle.getString("key");
        if (value != null) {

            startActivity(new Intent(MainActivity.this, secActivity.class));
        }
}

when app is in background or killed,FCM will not call onmessagerecieved method,but it will send data to system tray to display notification.so datapayload(sent from fcm console) will not be handled by onmessagerecieved method.when user click on notification,it will launch default activity of app and datapayload will be passed by intent .so making change in oncreate method of launcher activity(as above)we can get datapayload even when app is in background or killed.(ex key is sent by fcm console).when app is in foreground datapayload and will be handled by onmessagerecieved method of fcm service.

I have this same issue, and it’s driving me nuts. This project’s documentation isn’t helpful. It just says, “it’s tricky!” and links to a really old GCM issue: https://github.com/google/gcm/issues/63

Looks like if you want a hybrid notification to work properly when the app is in the background, you need to pass a click_action in your notification payload. Then in AndroidManifest.xml set MainActivity to respond to an intent with that click_action.

Feels like this behavior should be better documented. It’s taken a lot of trial and error to understand what’s really going on.

@dslounge

Ok, I think I’ve got it now. Thanks for explaining this thoroughly.

Still, I’m totally mystified as to why data is handled in OnMessageReceived when it’s passed on its own, but if it’s passed with notification it gets handled in the extras of the intent.

This really goes against the principle of least astonishment, and sort of screws up what would otherwise be an intuitive API.

screen shot 2016-10-25 at 7 43 17 pm