Unable to get notification data,body when app is in background or closed in React-native-firebase android

Viewed 6320

Im using react-native-firebase in my app for cloud messanging + notification. it get all body and data when app is in use but it cant get anything when app is closed or in background ....

I tried Headless JS but thats also not working

when i click on notification and when it open's the app its shows this {"google.priority":"high"}

thnaks in advance....

this is my android mainfest

<application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:allowBackup="false"
      android:theme="@style/AppTheme"
      android:largeHeap="true">
      <meta-data
    android:name="com.google.firebase.messaging.default_notification_icon"
    android:resource="@drawable/ic_stat_ic_notification" />
      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:launchMode="singleTop"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:windowSoftInputMode="adjustResize">

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
      </activity>
      <!---firebase -->
      <service android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService">
    <intent-filter>
      <action android:name="com.google.firebase.MESSAGING_EVENT" />
    </intent-filter>
  </service>
  <!-- <meta-data
    android:name="com.google.firebase.messaging.default_notification_channel_id"
    android:value="@string/default_notification_channel_id"/> -->
   <service android:name="io.invertase.firebase.messaging.RNFirebaseBackgroundMessagingService" />
  <!---firebase end-->
      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    </application>

this is my componentdidmount() function

 async componentDidMount() {
      this.getValueLocally();
      requestCameraLOCATION()

        const notificationOpen: NotificationOpen = await firebase.notifications().getInitialNotification();
        if (notificationOpen) {
            const action = notificationOpen.action;
            const notification: Notification = notificationOpen.notification;
            var seen = [];
            alert(JSON.stringify(notification.data, function(key, val) {
                if (val != null && typeof val == "object") {
                    if (seen.indexOf(val) >= 0) {
                        return;
                    }
                    seen.push(val);
                }
                return val;
            }));
        }
        const channel = new firebase.notifications.Android.Channel('test-channel', 'Test Channel', firebase.notifications.Android.Importance.Max)
                .setDescription('My apps test channel');
// Create the channel
        firebase.notifications().android.createChannel(channel);
        this.notificationDisplayedListener = firebase.notifications().onNotificationDisplayed((notification: Notification) => {
            // Process your notification as required
            // ANDROID: Remote notifications do not contain the channel ID. You will have to specify this manually if you'd like to re-display the notification.
        });
        this.notificationListener = firebase.notifications().onNotification((notification: Notification) => {
            // Process your notification as required
            notification
                .android.setChannelId('test-channel')
                .android.setSmallIcon('ic_launcher');
            firebase.notifications()
                .displayNotification(notification);

        });
        this.notificationOpenedListener = firebase.notifications().onNotificationOpened((notificationOpen: NotificationOpen) => {
            // Get the action triggered by the notification being opened
            const action = notificationOpen.action;
            // Get information about the notification that was opened
            const notification: Notification = notificationOpen.notification;
            var seen = [];
            alert(JSON.stringify(notification.data, function(key, val) {
                if (val != null && typeof val == "object") {
                    if (seen.indexOf(val) >= 0) {
                        return;
                    }
                    seen.push(val);
                }
                return val;
            }));
            firebase.notifications().removeDeliveredNotification(notification.notificationId);

        });
    }






              async checkPermission() {
                firebase.messaging().hasPermission()
                .then(enabled => {
                  if (enabled) {
                    this.getToken();
                  } else {
                    this.requestPermission();
                  }
                });}


                  async getToken() {
                    let fcmToken = await AsyncStorage.getItem('fcmToken');
                    if (!fcmToken) {
                      fcmToken = await firebase.messaging().getToken();
                      if (fcmToken) {
                        // user has a device token
                        await AsyncStorage.setItem('fcmToken', fcmToken);
                      }
                    }
                  }
                  async requestPermission() {
                    firebase.messaging().requestPermission()
                    .then(() => {
                      this.getToken();
                    })
                    .catch(error => {
                      console.warn(error);
                    });
                  }

and this is my bgMessaging.js

import firebase from 'react-native-firebase';
import type { RemoteMessage } from 'react-native-firebase';
import type { Notification,NotificationOpen} from 'react-native-firebase';

export default async (message: RemoteMessage) => {

    const newNotification = new firebase.notifications.Notification()
            .android.setChannelId(message.data.channelId)
            .setNotificationId(message.messageId)
            .setTitle(message.data.title)
            .setBody(message.data.body)
            .setSound("default")
            .setData(message.Data)
            .android.setAutoCancel(true)
            .android.setSmallIcon('ic_notification')
            .android.setCategory(firebase.notifications.Android.Category.Alarm)

    // Build a channel
    const channelId = new firebase.notifications.Android.Channel(message.data.channelId, channelName, firebase.notifications.Android.Importance.Max);

    // Create the channel
    firebase.notifications().android.createChannel(channelId);
    firebase.notifications().displayNotification(newNotification)

    return Promise.resolve();

}
2 Answers

there are two types of messages:

notification + data messages that will be handled by the FCM while in the background (so your code will not have access to the notification), and will call onNotification while in the foreground,

data-only messages will call headlessjs while in the background/closed and will call onMessage while in the foreground.

note: if you remove the title and body, your message will be categorized as the second one. also, data is optional in the first category.

to recap:

for data-only messages:

  • App in foreground : onMessage triggered

  • App in background/App closed : Background Handler (HeadlessJS)

for notification + data messages:

  • App in foreground : onNotification triggered

  • App in background/App closed : onNotificationOpened triggered if the notification is tapped

for more information and for iOS read the official docs for data-only messages and notification+data messages

Related