question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

onNotification not called when opening local notification in headless state (android)

See original GitHub issue

Bug

I want to handle remote push notifications (PN) from FCM in my app by sending silent remote PNs that trigger a local PN (as advised in this package’s troubleshooting guide). This works for all states but one: When the app is in quit state and receives a remote PN, the background task is launched, onNotification called and a local PN is created (PushNotification.configure is called as well). When this local PN is opened, the onNotification method is not called. If the app is in background state and receives a remote PN, the local PN is created and onNotification called as expected when it is opened.

Environment info

react-native info output:

System:
    OS: Windows 10 10.0.17763
    CPU: (8) x64 Intel(R) Core(TM) i7-7820HQ CPU @ 2.90GHz
    Memory: 20.04 GB / 31.85 GB
  Binaries:
    Node: 8.12.0 - C:\Program Files\nodejs\node.EXE
    Yarn: Not Found
    npm: 6.13.0 - C:\Program Files\nodejs\npm.CMD
    Watchman: Not Found
  SDKs:
    Android SDK:
      API Levels: 23, 25, 26, 27, 28
      Build Tools: 26.0.3, 27.0.3, 28.0.2, 28.0.3
      System Images: android-26 | Google APIs Intel x86 Atom_64, android-28 | Google APIs Intel x86 Atom, android-28 | Google APIs Intel x86 Atom_64
      Android NDK: Not Found
  IDEs:
    Android Studio: Version  3.6.0.0 AI-192.7142.36.36.6392135
  Languages:
    Java: Not Found
    Python: Not Found
  npmPackages:
    @react-native-community/cli: Not Found
    react: 16.9.0 => 16.9.0
    react-native: 0.62.0 => 0.62.0
  npmGlobalPackages:
    *react-native*: Not Found

Library version: 3.4.0

Steps To Reproduce

  1. Following this package’s installation instruction
  2. Setting up FCM
  3. Implemented a singleton notification interface that is called outside of the react scope (see index.js)
  4. Started app in debug mode on physical android device (SM-A520F) with Android 8.0.0
  5. Quit the app after it successfully started first
  6. Sent FCM message via Postman:
{
"to": "eGZXrIp-Suu4HTicVNzbjB:APA91bF5Y68YR-BvYtIpX_p1drT8Io5wTV1Mh_2Y6OGSgX_XzbP0rDQWIxj2YuRUBX6JiZvrshMHQ5t9FLxOp42fQfCUzRq9lKbsm4av0ECVlkeq0aQWlhV-kRDLwgIU03iXQbpl8uii",
"data": {
    "path": "Settings",  //data content
    "create_local": true,  //If a local PN should be created
    "text": "Remote notif"  //Text to display in local PN
  }
  "priority": "high",
  "content_available": true  //required for iOS silent PN
}
  1. Open local PN

Describe what you expected to happen:

  1. App background task spins up and onNotification is called with respective log output (“remote notif received”)
  2. Local PN is shown
  3. When local PN is opened, onNotification is called with log output “opened app with notif” (which unfortunately is not happening)

Log output for remote PN received in app background state and opening local PN:

log
[Tue May 12 2020 09:07:24.431]  LOG      configure
[Tue May 12 2020 09:07:24.432]  LOG      Running "SampleApp" with {"rootTag":21}
[Tue May 12 2020 09:07:24.433]  LOG      {"os": "android", "token": "eGZXrIp-Suu4HTicVNzbjB:APA91bF5Y68YR-BvYtIpX_p1drT8Io5wTV1Mh_2Y6OGSgX_XzbP0rDQWIxj2YuRUBX6JiZvrshMHQ5t9FLxOp42fQfCUzRq9lKbsm4av0ECVlkeq0aQWlhV-kRDLwgIU03iXQbpl8uii"}
[Tue May 12 2020 09:07:56.880]  LOG      onNotif
[Tue May 12 2020 09:07:56.950]  LOG      remote notif received {"data": {"create_local": "true", "path": "Settings", "text": "Remote notif"}, "finish": [Function finish], "foreground": false, "id": "1896499685", "userInteraction": false}
[Tue May 12 2020 09:07:58.817]  LOG      onNotif
[Tue May 12 2020 09:07:58.820]  LOG      opened app with notif {"actions": "[\"Yes\", \"No\"]", "alertAction": "view", "autoCancel": true, "bigText": "My big text that will be shown when notification is expanded", "category": "", "color": "red", "finish": [Function finish], "foreground": false, "group": "group", "id": "1", "largeIcon": "ic_launcher", "message": "My Notification Message", "number": "10", "ongoing": false, "playSound": false, "smallIcon": "ic_notification", "soundName": "default", "subText": "This is a subText", "tag": "some_tag", "ticker": "My Notification Ticker", "title": "Local Notification", "userInfo": {}, "userInteraction": true, "vibrate": true, "vibration": 300}

Log output for remote PN received in app quit state on spinning up background task and opening local PN:

log
[Tue May 12 2020 09:08:55.442]  LOG      configure
[Tue May 12 2020 09:08:55.443]  LOG      onNotif
[Tue May 12 2020 09:08:55.443]  LOG      remote notif received {"data": {"create_local": "true", "path": "Settings", "text": "Remote notif"}, "finish": [Function finish], "foreground": false, "id": "-538668049", "userInteraction": false}
[Tue May 12 2020 09:08:55.444]  LOG      {"os": "android", "token": "eGZXrIp-Suu4HTicVNzbjB:APA91bF5Y68YR-BvYtIpX_p1drT8Io5wTV1Mh_2Y6OGSgX_XzbP0rDQWIxj2YuRUBX6JiZvrshMHQ5t9FLxOp42fQfCUzRq9lKbsm4av0ECVlkeq0aQWlhV-kRDLwgIU03iXQbpl8uii"}
[Tue May 12 2020 09:09:00.701]  LOG      Running "SampleApp" with {"rootTag":1}

Reproducible sample code

index.js
import 'react-native-gesture-handler';
import {AppRegistry} from 'react-native';
import Routes from './src/config/routes';
import {name as appName} from './app.json';
import NotificationService from './src/libs/NotificationInterface';

NotificationService.getInstance();

AppRegistry.registerComponent(appName, () => Routes);
NotificationInterface.js
import PushNotification from 'react-native-push-notification';
import {AppState} from 'react-native';
import PushNotificationIOS from '@react-native-community/push-notification-ios';

export default class NotificationService {
  constructor() {
    this.configure(this.onRegister, this.onNotif);
    this.lastId = 0;
  }

  static instance = null;

  static getInstance() {
    if (this.instance == null) this.instance = new NotificationService();
    return this.instance;
  }

  onRegister = async token => {
    console.log(token);
  };

  onNotif = notif => {
    console.log('onNotif');
    if (
      notif.hasOwnProperty('data') &&
      notif.data.hasOwnProperty('create_local') &&
      notif.data.create_local
    ) {
      console.log('remote notif received', notif);
      if (!notif.foreground) {
        this.localNotif(notif.data.text);
      }
    } else {
      console.log('opened app with notif', notif);
      if (Platform.OS === 'ios') {
        PushNotificationIOS.setApplicationIconBadgeNumber(0);
      }
    }
    if (Platform.OS === 'ios') {
      notif.finish(PushNotificationIOS.FetchResult.NoData);
    }
  };

  configure(onRegister, onNotification) {
    console.log('configure');
    PushNotification.configure({
      onRegister: onRegister,
      onNotification: onNotification,
      permissions: {
        alert: true,
        badge: true,
        sound: true,
      },
      popInitialNotification: true,
      requestPermissions: true,
    });
  }

  localNotif() {
    this.lastId++;
    PushNotification.localNotification({
      /* Android Only Properties */
      id: '' + this.lastId, // (optional) Valid unique 32 bit integer specified as string. default: Autogenerated Unique ID
      ticker: 'My Notification Ticker', // (optional)
      autoCancel: true, // (optional) default: true
      largeIcon: 'ic_launcher', // (optional) default: "ic_launcher"
      smallIcon: 'ic_notification', // (optional) default: "ic_notification" with fallback for "ic_launcher"
      bigText: 'My big text that will be shown when notification is expanded', // (optional) default: "message" prop
      subText: 'This is a subText', // (optional) default: none
      color: 'red', // (optional) default: system default
      vibrate: true, // (optional) default: true
      vibration: 300, // vibration length in milliseconds, ignored if vibrate=false, default: 1000
      tag: 'some_tag', // (optional) add tag to message
      group: 'group', // (optional) add group to message
      ongoing: false, // (optional) set whether this is an "ongoing" notification

      /* iOS only properties */
      alertAction: 'view', // (optional) default: view
      category: '', // (optional) default: empty string
      userInfo: {}, // (optional) default: {} (using null throws a JSON value '<null>' error)

      /* iOS and Android properties */
      title: 'Local Notification', // (optional)
      message: 'My Notification Message', // (required)
      playSound: false, // (optional) default: true
      soundName: 'default', // (optional) Sound to play when the notification is shown. Value of 'default' plays the default sound. It can be set to a custom sound such as 'android.resource://com.xyz/raw/my_sound'. It will look for the 'my_sound' audio file in 'res/raw' directory and play it. default: 'default' (default sound is played)
      number: 10, // (optional) Valid 32 bit integer specified as string. default: none (Cannot be zero)
      actions: '["Yes", "No"]', // (Android only) See the doc for notification actions to know more
    });
  }

  scheduleNotif() {
    this.lastId++;
    PushNotification.localNotificationSchedule({
      date: new Date(Date.now() + 3000),  // in 3 secs

      /* Android Only Properties */
      id: '' + this.lastId, // (optional) Valid unique 32 bit integer specified as string. default: Autogenerated Unique ID
      ticker: 'My Notification Ticker', // (optional)
      autoCancel: true, // (optional) default: true
      largeIcon: 'ic_launcher', // (optional) default: "ic_launcher"
      smallIcon: 'ic_notification', // (optional) default: "ic_notification" with fallback for "ic_launcher"
      bigText: 'My big text that will be shown when notification is expanded', // (optional) default: "message" prop
      subText: 'This is a subText', // (optional) default: none
      color: 'blue', // (optional) default: system default
      vibrate: true, // (optional) default: true
      vibration: 300, // vibration length in milliseconds, ignored if vibrate=false, default: 1000
      tag: 'some_tag', // (optional) add tag to message
      group: 'group', // (optional) add group to message
      ongoing: false, // (optional) set whether this is an "ongoing" notification

      /* iOS only properties */
      alertAction: 'view', // (optional) default: view
      category: '', // (optional) default: empty string
      userInfo: {}, // (optional) default: {} (using null throws a JSON value '<null>' error)

      /* iOS and Android properties */
      title: 'Scheduled Notification', // (optional)
      message: 'My Notification Message', // (required)
      playSound: true, // (optional) default: true
      soundName: 'default', // (optional) Sound to play when the notification is shown. Value of 'default' plays the default sound. It can be set to a custom sound such as 'android.resource://com.xyz/raw/my_sound'. It will look for the 'my_sound' audio file in 'res/raw' directory and play it. default: 'default' (default sound is played)
    });
  }

  checkPermission(cbk) {
    return PushNotification.checkPermissions(cbk);
  }

  requestPermissions() {
    return PushNotification.requestPermissions();
  }

  cancelNotif() {
    PushNotification.cancelLocalNotifications({id: '' + this.lastId});
  }

  cancelAll() {
    PushNotification.cancelAllLocalNotifications();
  }
}

AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.sampleapp">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
    <uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.VIBRATE" />

    <application
            android:name=".MainApplication"
            android:label="@string/app_name"
            android:icon="@mipmap/ic_launcher"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:allowBackup="false"
            android:theme="@style/AppTheme">
        <activity
                android:name=".MainActivity"
                android:label="@string/app_name"
                android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
                android:windowSoftInputMode="adjustResize"
                android:exported="true"
                android:launchMode="singleInstance">
        </activity>
        <activity
                android:name="com.zoontek.rnbootsplash.RNBootSplashActivity"
                android:theme="@style/BootTheme"> <!-- apply the theme you created at step 3. -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
                <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>
            </intent-filter>
        </activity>
        <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />


        <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationPublisher" />
        <receiver android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationBootEventReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>

        <service
                android:name="com.dieam.reactnativepushnotification.modules.RNPushNotificationListenerService"
                android:exported="false" >
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>

        <meta-data  android:name="com.dieam.reactnativepushnotification.notification_channel_name"
                    android:value="sampleapp"/>
        <meta-data  android:name="com.dieam.reactnativepushnotification.notification_channel_description"
                    android:value="Sample App test channel"/>
        <meta-data  android:name="com.dieam.reactnativepushnotification.notification_foreground"
                    android:value="false"/>
        <meta-data  android:name="com.dieam.reactnativepushnotification.notification_color"
                    android:resource="@android:color/white"/>
    </application>

</manifest>

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:18

github_iconTop GitHub Comments

9reactions
Ajmal0197commented, Sep 5, 2020

The issue is due to splash activity Edit the manifest like this and it gonna work:

      <activity
        android:name=".SplashActivity"
        android:theme="@style/SplashTheme"
        android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
  <activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
    android:windowSoftInputMode="adjustResize" >
      <intent-filter>
      <action android:name="android.intent.action.MAIN" />
      <category android:name="android.intent.category.INFO" />
      </intent-filter>
    </activity>
1reaction
Dallas62commented, May 20, 2020

Hi @MarcoStb1993 A pull request fix this issue without a workaround: #1446 This will be release soon.

Read more comments on GitHub >

github_iconTop Results From Across the Web

onNotification() is not fired when app is killed - Stack Overflow
I am not positive but when I remember correctly killing (alias force closing) an app disables the onNotification functionality in Android ...
Read more >
Local Notification Not Triggering In Android 10 - ADocLib
Bug I want to handle remote push notifications (PN) from FCM in my onNotification not called when opening local notification in headless state...
Read more >
Cloud Messaging | React Native Firebase
To learn more about local notifications, view the Notifications documentation. ... state, the onMessage handler will not be called when receiving messages.
Read more >
Events | Notifee
Notifee exposes a getInitialNotification method on Android, which can be called early on in your React lifecycle to obtain the notification which opened...
Read more >
navigating user on notification click app in background ...
Coding example for the question navigating user on notification click app in ... not working in react native when app is in background...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found