invertase / react-native-firebase

🔥 A well-tested feature-rich modular Firebase implementation for React Native. Supports both iOS & Android platforms for all Firebase services.
https://rnfirebase.io
Other
11.71k stars 2.22k forks source link

[Android] [Notification] [launchMode="singleTask"] On tap of local notification, 'onNotificationOpened' is not getting triggered. #1230

Closed rajatyadav closed 6 years ago

rajatyadav commented 6 years ago

Issue

I have setup notification for iOS and Android. All notifications and 'tap' behaviour is working fine except one. In case of Android, when app is in foreground and I am getting any notification, then I am using firebase.notifications().displayNotification() To push local notification.

According to document, when I will tap on this notification it suppose to trigger, firebase.notifications().onNotificationOpened() which is not happening.

Notification Code

const FCM = firebase.messaging();
const FCN = firebase.notifications();

const channel = new firebase.notifications.Android.Channel(
  'all',
  'All Notifications',
  firebase.notifications.Android.Importance.Max
).setDescription('All notifications');

FCN.android.createChannel(channel);

this.notificationListener = FCN.onNotification((notif: Notification) => {
  if (Platform.OS === 'android') {
    const localNotification = new firebase.notifications.Notification({
        sound: 'default',
        show_in_foreground: true,
        local: true
      })
      .setNotificationId(notif.notificationId)
      .setTitle(notif.title)
      .setSubtitle(notif.Subtitle)
      .setBody(notif.body)
      .setData(notif.data)
      .android.setClickAction(notif.android.clickAction)
      .android.setBigText(notif.body)
      .android.setChannelId('all')
      .android.setSmallIcon('ic_notif')
      .android.setLargeIcon('ic_launcher')
      .android.setPriority(firebase.notifications.Android.Priority.High);

    firebase.notifications()
      .displayNotification(localNotification)
      .catch(err => console.error(err));
  } else if (Platform.OS === 'ios') {
    const localNotification = new firebase.notifications.Notification({
        content_available: true
      })
      .setNotificationId(notif.notificationId)
      .setTitle(notif.title)
      .setSubtitle(notif.subtitle)
      .setBody(notif.body)
      .setData(notif.data)
      .ios.setBadge(notif.ios.badge);

    firebase.notifications()
      .displayNotification(localNotification)
      .catch(err => console.error(err));
  }
});

this.notificationOnOpenListener = FCN.onNotificationOpened((notif: NotificationOpen) => {
  if (notif) this.props.navigateToThis(notif.notification);
});

FCN.getInitialNotification().then(payload => {
  if (payload) this.props.navigateToThis(payload.notification);
});

build.gradle

buildscript {
    repositories {
        jcenter()
        google()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.1.2'
        classpath 'com.google.gms:google-services:3.2.1'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        mavenLocal()
        jcenter()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
        google()
    }
}

Dependencies

dependencies {
    implementation(project(':react-native-firebase')) {
        transitive = false
    }
    implementation 'com.google.android.gms:play-services-base:15.0.0'
    implementation 'com.google.android.gms:play-services-maps:15.0.0'
    implementation "com.google.firebase:firebase-core:15.0.2"
    implementation "com.google.firebase:firebase-messaging:15.0.2"
    implementation "me.leolin:ShortcutBadger:1.1.21@aar"
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "com.android.support:appcompat-v7:23.0.1"
    implementation "com.facebook.react:react-native:+"  // From node_modules
}

I also have another change I made which is

android:launchMode="singleTask"

in documentation it is

android:launchMode="singleTop"

Environment

1. Application Target Platform: Android - targetSdkVersion 22 2. Development Operating System: macOS High Sierra 3. React Native version: 0.55.4 4. RNFirebase Version: 4.2.0 5. Firebase Module: 15.0.2

saloni-springct commented 6 years ago

In my case, "onNotificationOpened" is being called when notification is clicked from system tray, however the notification still sits in the tray; it is not being cleared / removed from the tray.

rajatyadav commented 6 years ago

@saloni-springct if I am not wrong, you might be using android:launchMode="singleTop". Similar case happened with me when I used launched mode "singleTop"

vomchik commented 6 years ago

@rajatyadav hey, maybe it will be useful for you https://github.com/invertase/react-native-firebase/issues/1272#issuecomment-403564399

saloni-springct commented 6 years ago

Hey, @rajatyadav I got this working. Yes, launchMode is singleTop. I had to set the notification.android.setAutoCancel(true); to clear the notification from system tray.

rajatyadav commented 6 years ago

@vomchik my code is same as you suggested,

@Override
    public void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
}

Not working for me. My issue is only on one state, when the app is in foreground. In that case 'onNotificationOpened' not working

saloni-springct commented 6 years ago

Hey @rajatyadav

Do you have this in your AndroidManifest?

<service android:name="io.invertase.firebase.messaging.RNFirebaseMessagingService">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT"/>
            </intent-filter>
        </service>
rajatyadav commented 6 years ago

Hey @saloni-springct, yes I have same code in AndroidManifest.

Salakar commented 6 years ago

Can you guys confirm which one is the issue - in the foreground or the background?

Are you aware that onNotificationOpened is background only as specified in the tables here?

image

For the foreground you need to be using onNotification.

laukaichung commented 6 years ago

@Salakar onNotification isn't triggered when the app is in the foreground. When I tap the local notification in the background, it just brings the app to the foreground, but onNotificationOpened isn't triggered.

onNotificationDisplayed works fine when notifications are shown. Removing or Adding android:launchMode="singleTop" has no effect.

I'm using react native navigation v2, react-native 0.56.

laukaichung commented 6 years ago

Just an update:

Neither of these two message objects sent from the server works on click:

var message = {
  notification: {
    title: '$GOOG up 1.43% on the day',
    body: '$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.'
  }
};
var message = {
  data: {
    title: '$GOOG up 1.43% on the day',
    body: '$GOOG gained 11.80 points to close at 835.67, up 1.43% on the day.',
    customData:"some Data"
  }
};
abhigupta92 commented 6 years ago

Is there any update on the solution to this problem ? IOS works fine.

Android : App Closed : getInitialNotification Listener Triggered when app opened by clicking the notification. App in Foreground/Background : onNotificationOpened Listener never gets triggered when app opened through clicking the notification.

Please post the solution if anyone knows 🙏

Edit :

I would like to add some things that I set up too :

nikhilboranaarit commented 6 years ago

https://github.com/invertase/react-native-firebase/issues/1272#issuecomment-421424104 it worked for me try this solution..

abhigupta92 commented 6 years ago

Hey @nikhilboranaarit , the above solution did work for me, but I don't have a splash screen, so I put it in MainApplication file. But this is just a hack to restart the Application, so that the getInitialNotification is triggered. It is not triggering the onNotificationOpened listener :) . Nevertheless, my app is not so heavy, so restarting the app on notification click is not a problem to me, plus there is no solution posted yet to this problem 👍

hanarahmati commented 6 years ago

@nikhilboranaarit did you find a way for getting notification when app in background or when app closed?

moret commented 6 years ago

Let me add some user feedback about this subject. Only on Android I also noted that plain, locally displayed notifications, when tapped, were not triggering onNotificationOpened while the the app was in foreground or background, and getInitialNotification resolved null when the app was closed.

My setup was also using react-native-splash-screen, which even has an open issue on this subject. I tried the proposed workarounds, but that meant restarting the app once a notification is tapped and using getInitialNotification every time instead of onNotificationOpened on Android.

In the end I removed the react-native-splash-screen setup, so now I have one single <activity>, with android:launchMode="singleTop" on it. Once I did that the taps behaved as expected: when tapped, onNotificationOpened gets triggered while the the app was in foreground or background, and getInitialNotification resolves to a NotificationOpen object with the displayed notification as payload when the app was closed.

I'm not proficient enough on Android apps to propose a setup that would still have two <activity> entries and behave as described in the docs - specially without the restarts. I'll probably live without the splash for now, but I hope this description helps someone who knows these setups better to come up with a combination that satisfies both needs.

Salakar commented 6 years ago

Duplicate of #1149 and many others, let's track all onNotificationOpened issues in one place please (same platform or not please discuss on #1149).

Thanks

pawankhadpe commented 5 years ago

Is there any update on the solution to this problem ? IOS works fine.

Android : App Closed : getInitialNotification Listener Triggered when app opened by clicking the notification. App in Foreground/Background : onNotificationOpened Listener never gets triggered when app opened through clicking the notification.

Please post the solution if anyone knows 🙏

Edit :

I would like to add some things that I set up too :

  • I have a onNotification Listener which gets triggered if the app is in Foreground/Background when I send it through my server ( PHP script ). I use react-native-firebase notifications to display the notification ( I parse the information and create a firebase Notification Object, This part works just fine ). The part which doesn't work is now when I click the corresponding notification, the onNotificationOpened should be triggered but is not getting triggered.

Hi @abhigupta92 , @Salakar : In ioS : When app is closed : const notificationOpen = await firebase.notifications().getInitialNotification(); gets called.

But when app is in foreground : onNotification , doesnt get called . But when app is in background : onNotificationOpened , doesnt get called.

I am using "react-native": "0.57.5", "react-native-firebase": "^5.1.1", my code below : import type , { Notification ,NotificationOpen} from 'react-native-firebase';

async componentDidMount() {

    this.notificationDisplayedListener = firebase.notifications().onNotificationDisplayed((notification) => {
        console.log("notificationDisplayedListener", notification);
        const { title, body } = notification;
        this.showAlert(title, body);

      });

     this.notificationListener = firebase.notifications().onNotification((notification: Notification) => {
      console.log("notificationListener", notification);
      const { title, body } = notification;

        //  this.readNotificationData(notification);
          this.showAlert(title, body);
      });

      /*
      * Triggered when a particular notification has been received in foreground ,background
      * */

  this.notificationOpenedListener = firebase.notifications().onNotificationOpened((notificationOpen) => {
    const notification: Notification = notificationOpen.notification;
    const { title, body } = notification;
      //  this.readNotificationData(notification);
        this.showAlert(title, body);
});

const notificationOpen = await firebase.notifications().getInitialNotification(); if (notificationOpen) { const notification: Notification = notificationOpen.notification; const { title, body } = notification; this.showAlert(title, body); }

}

Please advise how it works for you on iOS . I am using iOS 11.2

TwistedMinda commented 1 year ago

Duplicate of https://github.com/wix/react-native-notifications/issues/958 too, I think. Problem doesn't seem to be related to Firebase specifically.