Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android: onBackgroundEvent not fired when quick action is pressed #404

Closed
amjadbouhouch opened this issue May 13, 2022 · 67 comments · Fixed by #603
Closed

Android: onBackgroundEvent not fired when quick action is pressed #404

amjadbouhouch opened this issue May 13, 2022 · 67 comments · Fixed by #603

Comments

@amjadbouhouch
Copy link

I've a notification with two actions (accept call/ reject call).

 android: {
        channelId: callChannelId,
        category: AndroidCategory.CALL,
        circularLargeIcon: true,

        color: AndroidColor.BLUE,

        // Recommended to set importance to high

        importance: AndroidImportance.HIGH,
        ongoing: true,
        fullScreenAction: {
          id: 'incoming-call',
        },
        largeIcon: largeIcon,

        // smallIcon: 'name-of-a-small-icon', // optional, defaults to 'ic_launcher'.

        actions: [
          {
            title: 'Reject',
            pressAction: { id: NOTIFICATION_ACTIONS_ID.cancelIncomingCall },
          },
          {
            title: 'Accept',
            pressAction: { id: NOTIFICATION_ACTIONS_ID.acceptIncomingCall, launchActivity: 'default' },
          },
        ],
        badgeCount: 1,
        timeoutAfter: ONE_MINUTE,
        autoCancel: false,
      },

handleOnForegroundEvent works fine.
And now I'm trying to add handleOnForegroundEvent: The notification get displayed in killed state and handleOnForegroundEvent fired once then when I pressed I can't get wich action get pressed because onBackgroundEvent not fired when I pressed.

notifee.onBackgroundEvent(async ({ type, detail }) => {

  const { notification, pressAction } = detail;
    

    if (type === EventType.ACTION_PRESS) {
      if (pressAction.id === NOTIFICATION_ACTIONS_ID.acceptIncomingCall || type === EventType.PRESS) {
        // accept call
        incomingCallNotifications.handleAcceptCall(notification);
      } else {
        incomingCallNotifications.handleRejectCall(notification);
      }

      return;
    }
});

Package.json

"@notifee/react-native": "^5.0.3",
"react-native": "0.67.4",
@helenaford
Copy link
Member

Hi, it sounds like there's an issue with onBackgroundEvent rather than action_press, where in your project have you put onBackgroundEvent? We have an example app that might help, you can pull it down and run it

@helenaford helenaford added the needs-feedback Waiting on response to questions label May 15, 2022
@amjadbouhouch
Copy link
Author

Hi @helenaford, and thank your for your response!
I Totaly agree with you! I tried to run it on different device but I still have the same issue!
This is my index.js

/**
 * @format
 */

import messaging from '@react-native-firebase/messaging';
import { AppRegistry } from 'react-native';
import notifee from '@notifee/react-native';
import App from './App';
import { name as appName } from './app.json';
import firebaseNotificationHandler from './app/utils/firebaseNotificationHandler';

// Fired when the notification get displayed but not when an action get pressed!
notifee.onBackgroundEvent(async ({ type, detail }) => {
  const { notification, pressAction } = detail;
  if (type === EventType.ACTION_PRESS) {
    if (pressAction.id === NOTIFICATION_ACTIONS_ID.acceptIncomingCall || type === EventType.PRESS) {
      // accept call This is works because I set launchActivity: 'default'
      incomingCallNotifications.handleAcceptCall(notification);
    } else {
      incomingCallNotifications.handleRejectCall(notification);
     // handleRejectCall function
      axios
      .get(`${API_URL}/....`, {
        headers: {
          Authorization: accessToken,
        },
      })
      .catch((err) => {});
    }
  }
});
// display notification when app is in foreground
messaging().onMessage(firebaseNotificationHandler.onMessageReceived);
// display notification when app is in background
messaging().setBackgroundMessageHandler(firebaseNotificationHandler.onMessageReceived);

AppRegistry.registerComponent(appName, () => App);

I'm thinking setting launchActivity: 'default' and when the app opened I can called handleRejectCall

@amjadbouhouch
Copy link
Author

I downgrade from @notifee/react-native@5.2.1 to @notifee/react-native@4.0.1 and now onBackgroundEvent works fine when the app in killed state!

onBackgroundEvent from the example

notifee.onBackgroundEvent(async ({ type, detail }) => {
  const { notification, pressAction } = detail;
  console.log(`[onBackgroundEvent] notification id: ${notification?.id},  event type: ${EventType[type]}, press action: ${pressAction?.id}`);
  // Check if the user pressed the "Mark as read" action
  if (type === EventType.ACTION_PRESS && pressAction?.id === NOTIFICATION_ACTIONS_ID.cancelIncomingCall) {
    console.log('[onBackgroundEvent] ACTION_PRESS: cancelIncomingCall');

    // Remove the notification
    if (notification?.id) {
      await notifee.cancelNotification(notification?.id);
    }
  } else if (type === EventType.ACTION_PRESS && pressAction?.id === NOTIFICATION_ACTIONS_ID.acceptIncomingCall) {
    console.log('[onBackgroundEvent] ACTION_PRESS: acceptIncomingCall');

    // Remove the notification
    if (notification?.id) {
      await notifee.cancelNotification(notification?.id);
    }
  }
});

@notifee/react-native@4.0.1 Logs ✅

 LOG  [onBackgroundEvent] notification id: 0UCHEweojRsL,  event type: DELIVERED, press action: undefined
 LOG  [onBackgroundEvent] notification id: 0UCHEweojRsL,  event type: ACTION_PRESS, press action: cancelIncomingCal

@notifee/react-native@5.2.1 Logs ❌

 LOG  [onBackgroundEvent] notification id: 0UCHEweojRsL,  event type: DELIVERED, press action: undefined

When an action get pressed onBackgroundEvent never get called

@mikehardy
Copy link
Contributor

🤔 hmm - what's the execution environment here? I don't see that specified (android vs ios)

Our releases are usually pretty small so even though the range is large, the actual number of functional (non-test, non-docs) commits is pretty small:

@notifee/react-native@4.0.1...@notifee/react-native@5.2.1

Total release count is 8 so if you attempted to bisect which release starts to fail it would probably take just 3 attempts before you located the precise commit and we'd have the bug on the dissection table 🔬

@amjadbouhouch
Copy link
Author

Hi, @mikehardy, first thank you for your time!
OK sounds good to me, I'll try my best to find which commit!

Android environment

OS: Ubuntu 22.04 LTS
Phne: Android 11 (real device)

IOS environment

OS: iMac (macOs Montery version 12.3.1)
Xcode: 13.3.1
Phone: iPhone 11

React native

"react-native": "0.67.4",

I hope that can help

@amjadbouhouch
Copy link
Author

It stops working from version 4.1.0 and above
CHANGELOG 4.0.1 : https://notifee.app/react-native/docs/release-notes#410

I don't want to downgrade, I remember there is a reason upgrading to v 5+ in IOS

@mikehardy
Copy link
Contributor

That's great though! Really tight range of commits!

Only 3

1- 50aa11e - going to say it's not that, it's only a model change, and java specific

2- f5da722 - maybe this one? But it is java only, and you did not differentiate on the failure, you indicated it was android and ios? Not sure how this could affect iOS as well

3- ed22c8f - massive change, but is also java only

If the result of 4.0.1 working and 4.1.0 not working is to be believed, I'm confused how it could manifest on iOS. Can you confirm that this happens on both android and ios? If it is on both then there is something really subtle going on and will need some thinking. If it's actually android only then we pick apart the specific commits and find it

@amjadbouhouch
Copy link
Author

@mikehardy it's an android only!
I just finished uploading the IOS APP to testflight, I'll test soon and I I will give you a feedback.

I tried intalling specific commit like this : "@notifee/react-native": "git+https://github.com/invertase/notifee.git#ed22c8ff35ec1c69dc1015709920e50d835f3c57" . it successfully installed but I couldn't run it. I don't know if this is the propre way or not to know witch commit breaks!

Should I downgrade!

@mikehardy
Copy link
Contributor

Excellent! That means our methodology is correct - or at least it seems to be - you saying it is android only means we do seem to be testing what I think we're testing since it's android only changes in the version change that started the problem

Excellent again if you are willing to install from a commit hash. I think the only step missing is to build the typescript source after install, calling this:

"build": "genversion --es6 --semi src/version.ts && tsc",

When I've done this for notifee before I've put this in a package.json::postinstall script: cd node_modules/@notifee/react-native && yarn build - I think that will do it? I apologize I haven't tested before hitting send here but I think typescript -> javascript is the missing step when you go from source vs our npm downloaded package

@mikehardy
Copy link
Contributor

oh, I think it needs tsc etc, so you probably have to do cd node_modules/@notifee/react-native && yarn && yarn build

@hussainimp
Copy link

We are also facing the same issue.
I think Android 12 changes has impacted this.
There might be something related with Notification Trampoline - https://developer.android.com/about/versions/12/behavior-changes-12#notification-trampolines

@mikehardy
Copy link
Contributor

@hussainimp indeed, it is almost undoubtedly this commit ed22c8f - just not sure exactly what yet - we can use all the help we can get with regard to isolating the specific issue and ideally 🙏 🙏 seeing a PR from someone affected - I can collaborate with anyone to get a fix released but this is not a personal use case of mine so it's not personally urgent and I won't have time to personally fix it at the moment, it will end up on the general work pile and might sit otherwise

@amjadbouhouch
Copy link
Author

I tried yesterday installing one of three commits but not luck, I think I have some conflict with tsc version - I will give it another try because I really need this to work.

@fabyeah
Copy link

fabyeah commented Jun 1, 2022

I have the same problem.

Only android is affected (testing on Pixel 5, Android 12).

It works with the local test build, but not with the release build.

In February I upgraded from ^1.11.1 to ^4.0.1.

So 4.0.1 and even 4.0.0 don't work for me.

Somehow I can't get 3.0.4 to run on my phone. The app will close immediately.

On the emulator i can install 3.0.4 but don't receive notifications (probably because of some missing setup), so I can't test and narrow it down more.

As it is not working for me even prior to 4.1.0 i'm not sure it's notifee/version related. It might be related to some change in Android 12? I noticed the problem some time ago and am not 100% sure it started directly after the notifee upgrade. Also minor detail, in 4.0.0 there was this breaking change:

the minimum compileSdkVersion required has increased to 31,

My app is solely for the purpose of receiving notifications which open web links, so this issue is completely breaking my app.

:(

@fabyeah
Copy link

fabyeah commented Jun 3, 2022

I fixed the emulator and tested some more. With Android 11, 4.0.1 is working, but with Android 12 it is not. Sometimes I have observed it working when the app is in the background, but never when the app is terminated.

@amjadbouhouch can you confirm that the release version is working for you on Android 12? Or how did you test it? I feel like this is broken for Android 12 in all notifee versions.

@helenaford is ed22c8f supposed to fix this issue or something else? Are there now some restrictions with Android 12 that prohibit the following:

My code in index.js:

if (Platform.OS === 'android') {
  notifee.onBackgroundEvent(async ({ type, detail }) => {
    const { notification } = detail;
    // Open the link in the browser when user presses notification.
    if (type === EventType.PRESS) {
      await Linking.openURL(notification.data.url);
    }
  });
}

@amjadbouhouch
Copy link
Author

Hi @fabyeah, unfortunately it's not working.
I end up downgrading my my targetSdkVersion from 31 to 30
This is what I have now :

build.gradle

ext {
        buildToolsVersion = "30.0.2"
        minSdkVersion = 21
        compileSdkVersion = 31
        targetSdkVersion = 30
        ndkVersion = "21.4.7075529"
    }

gradle version


distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip

package.json

"@notifee/react-native": "^5.2.2",
"react-native": "0.67.4",

index.js

/**
 * @format
 */

import messaging from '@react-native-firebase/messaging';
import { AppRegistry } from 'react-native';
import App from './App';
import { name as appName } from './app.json';
import firebaseNotificationHandler from './app/utils/firebaseNotificationHandler';
// firebase
messaging().onMessage(firebaseNotificationHandler.onMessageReceived);
messaging().setBackgroundMessageHandler(firebaseNotificationHandler.onMessageReceived);
// notifee, same function as OnForegroundEvent
notifee.onBackgroundEvent(async (props) => firebaseNotificationHandler.handleOnForegroundEvent(props));
AppRegistry.registerComponent(appName, () => App);

functions:

 // on foreground notification pressed;

  handleOnForegroundEvent({ type, detail: { notification, pressAction } }: any) {
    const notificationData = JSON.parse(notification.data.notification);
    if (type === EventType.ACTION_PRESS && pressAction?.id === NOTIFICATION_ACTIONS_ID.acceptIncomingCall) {
      return incomingCallNotifications.handleAcceptCall(notificationData);
    }
    if (type === EventType.ACTION_PRESS && pressAction?.id === NOTIFICATION_ACTIONS_ID.cancelIncomingCall) {
      return incomingCallNotifications.handleRejectCall(notificationData);
    }
    if (type !== EventType.PRESS) {
      return Promise.resolve();
    }
    return firebaseNotificationHandler.handleInitialNotification(notificationData);
  },
  
   async handleRejectCall(notification: IIcomingCallNotification) {
    const { conversationId, notificationId } = notification;
    const accessToken = await load('accessToken');

    axios
      .get(..............)
    if (notificationId) {
      await notifee.cancelNotification(notificationId);
    }
  }
  
    async makeIncomingCallNotification(title: string, body: string, user: any, notification?: any) {
    const callChannelId = await notifee.createChannel(INCOMING_CHANNEL_OPTIONS);
    const notificationId = generateId();
    const largeIcon = getNotificationLargeIconByUser(user);

    if (isIOS) {
      await getIosCategory();
    }

    await notifee.displayNotification({
      title: title,
      body: body,
      id: notificationId,
      android: {
        channelId: callChannelId,
        category: AndroidCategory.CALL,
        circularLargeIcon: true,

        color: AndroidColor.BLUE,

        // Recommended to set importance to high

        importance: AndroidImportance.HIGH,
        ongoing: true,

        largeIcon: largeIcon,

        // smallIcon: 'name-of-a-small-icon', // optional, defaults to 'ic_launcher'.
        pressAction: {
          id: NOTIFICATION_ACTIONS_ID.acceptIncomingCall,
        },
        actions: [
          {
            title: '<span style="color: #FF0000;">Réfuser</span>',
            pressAction: { id: NOTIFICATION_ACTIONS_ID.cancelIncomingCall },
          },
          {
            title: '<span style="color: #00FF00;">Accepter</span>',
            pressAction: { id: NOTIFICATION_ACTIONS_ID.acceptIncomingCall },
          },
        ],
        badgeCount: 1,
        timeoutAfter: ONE_MINUTE,
        autoCancel: false,
      },
      ios: {
        categoryId: 'incoming-call',
        attachments: [
          {
            // iOS resource

            url: largeIcon,
            thumbnailHidden: true,
          },
        ],
        foregroundPresentationOptions: {
          alert: true,
          sound: true,
        },

        critical: true,
      },
      data: {
        notification: JSON.stringify({ ...notification, notificationId }),
      },
    });
  },

@mikehardy
Copy link
Contributor

Output from adb logcat at time of reproduction might be interesting, if Android 12 background execution limits are blocking this (despite that commit linked above, that should fix them...) then logcat typically tells you why in form of system logging reasons

@fabyeah
Copy link

fabyeah commented Jun 3, 2022

@mikehardy
The error in Logcat when the app is terminated is this:

Indirect notification activity start (trampoline) from [app-id] blocked

So seems to be the same as #250 where the proposed fix is to downgrade from targetSdkVersion = 31 to targetSdkVersion = 30. I was indeed on 31, because react-native-bootsplash says to set it: https://github.com/zoontek/react-native-bootsplash#android-1

I downgraded and pressing notifications works now. 👍
(and the boot screen still shows)

@mikehardy mikehardy added bug help wanted android 12 and removed needs-feedback Waiting on response to questions labels Jun 3, 2022
@mikehardy mikehardy changed the title notifee.onBackgroundEvent get called once when the notification displayed but not when action get pressed! [targetSdkVersion 31] notifee.onBackgroundEvent get called once when the notification displayed but not when action get pressed! Jun 3, 2022
@mikehardy
Copy link
Contributor

Oh darn, that was supposed to be fixed in 4.1.0
Okay, re-labeled this one and tagged it up

@fabyeah
Copy link

fabyeah commented Jun 4, 2022

@mikehardy I was testing with 4.0.1! The following is the log when testing with current 5.3.0 (and targetSdkVersion = 31) and pressing the notification. Sorry for the confusion. Can't see an obvious error here, but still nothing happens.

2022-06-04 18:09:19.214 1332-1332/? I/GoogleInputMethodService: GoogleInputMethodService.onFinishInput():3420 
2022-06-04 18:09:19.215 1332-1332/? I/GoogleInputMethodService: GoogleInputMethodService.onStartInput():2002 
2022-06-04 18:09:19.216 1332-1332/? I/DeviceUnlockedTag: DeviceUnlockedTag.notifyDeviceLockStatusChanged():31 Notify device unlocked.
2022-06-04 18:09:19.266 1049-1563/? D/EGL_emulation: app_time_stats: avg=161.10ms min=17.93ms max=804.71ms count=6
2022-06-04 18:09:19.330 738-738/? D/StatusBar: disable<e i a s b h r c s > disable2<q i n >
2022-06-04 18:09:19.392 738-906/? D/EGL_emulation: app_time_stats: avg=110.89ms min=8.53ms max=447.18ms count=10
2022-06-04 18:09:19.459 329-375/? W/RanchuHwc: validateDisplay: layer 86 CompositionType 1, fallback
2022-06-04 18:09:19.493 329-375/? W/RanchuHwc: presentDisplay display has no layers to compose, flushing client target buffer.
2022-06-04 18:09:19.515 329-375/? W/RanchuHwc: validateDisplay: layer 86 CompositionType 1, fallback
2022-06-04 18:09:19.543 329-375/? W/RanchuHwc: presentDisplay display has no layers to compose, flushing client target buffer.
2022-06-04 18:09:21.849 738-906/? D/EGL_emulation: app_time_stats: avg=116.69ms min=7.03ms max=1588.63ms count=20
2022-06-04 18:09:21.941 738-738/? D/ActivityLaunchAnimator: Starting intent with a launch animation
2022-06-04 18:09:21.944 537-552/? I/ActivityTaskManager: START u0 {flg=0x18080000 cmp=[app-id]/app.notifee.core.NotificationReceiverActivity (has extras)} from uid 10153
2022-06-04 18:09:21.945 537-552/? W/ActivityTaskManager: Can't find TaskDisplayArea to determine support for multi window. Task id=21 attached=false
2022-06-04 18:09:21.966 738-738/? D/ActivityLaunchAnimator: launchResult=0 willAnimate=true isOnKeyguard=false
2022-06-04 18:09:21.966 537-877/? W/ActivityTaskManager: Tried to set launchTime (0) < mLastActivityLaunchTime (1531791)
2022-06-04 18:09:22.032 738-839/? D/ActivityLaunchAnimator: Remote animation was cancelled
2022-06-04 18:09:22.057 738-939/? D/PeopleSpaceWidgetMgr: Sbn doesn't contain valid PeopleTileKey: null/0/[app-id]
2022-06-04 18:09:22.059 738-738/? V/ShadeControllerImpl: NotificationShadeWindow: com.android.systemui.statusbar.phone.NotificationShadeWindowView{856af3 V.E...... ........ 0,0-1080,2280} canPanelBeCollapsed(): true
2022-06-04 18:09:22.073 537-3098/? W/ActivityManager: Unable to start service Intent { act=android.service.smartspace.SmartspaceService cmp=com.google.android.as/com.google.android.apps.miphone.aiai.app.AiAiSmartspaceService } U=0: not found
2022-06-04 18:09:22.073 537-3098/? W/RemoteSmartspaceService: could not bind to Intent { act=android.service.smartspace.SmartspaceService cmp=com.google.android.as/com.google.android.apps.miphone.aiai.app.AiAiSmartspaceService } using flags 67112961
2022-06-04 18:09:22.074 537-537/? W/ActivityManager: Unbind failed: could not find connection for android.app.LoadedApk$ServiceDispatcher$InnerConnection@9689660
2022-06-04 18:09:22.092 7070-7253/? I/ReactNativeJNI: Memory warning (pressure level: TRIM_MEMORY_UI_HIDDEN) received by JS VM, ignoring because it's non-severe
2022-06-04 18:09:22.115 537-3098/? W/InputManager-JNI: Input channel object 'e197bbb com.google.android.calendar/com.google.android.calendar.launch.oobe.WhatsNewFullScreen (client)' was disposed without first being removed with the input manager!
2022-06-04 18:09:22.131 1332-1332/? I/GoogleInputMethodService: GoogleInputMethodService.onFinishInput():3420 
2022-06-04 18:09:22.132 1332-1332/? I/GoogleInputMethodService: GoogleInputMethodService.onStartInput():2002 
2022-06-04 18:09:22.134 1332-1332/? I/DeviceUnlockedTag: DeviceUnlockedTag.notifyDeviceLockStatusChanged():31 Notify device unlocked.
2022-06-04 18:09:22.181 1049-1563/? D/EGL_emulation: app_time_stats: avg=479.51ms min=8.32ms max=2733.51ms count=6
2022-06-04 18:09:22.195 537-564/? W/ActivityTaskManager: Can't find TaskDisplayArea to determine support for multi window. Task id=19 attached=false
2022-06-04 18:09:22.195 537-564/? W/ActivityTaskManager: Can't find TaskDisplayArea to determine support for multi window. Task id=19 attached=false
2022-06-04 18:09:22.248 537-570/? W/UsageStatsService: Unexpected activity event reported! (com.google.android.calendar/com.google.android.calendar.launch.oobe.WhatsNewFullScreen event : 23 instanceId : 118650254)
2022-06-04 18:09:22.248 537-570/? W/UsageStatsService: Unexpected activity event reported! (com.google.android.calendar/com.android.calendar.event.LaunchInfoActivity event : 23 instanceId : 87039518)
2022-06-04 18:09:22.543 329-375/? W/RanchuHwc: validateDisplay: layer 90 CompositionType 1, fallback
2022-06-04 18:09:22.548 329-375/? W/RanchuHwc: presentDisplay display has no layers to compose, flushing client target buffer.
2022-06-04 18:09:22.557 329-375/? W/RanchuHwc: validateDisplay: layer 90 CompositionType 1, fallback
2022-06-04 18:09:22.576 329-375/? W/RanchuHwc: presentDisplay display has no layers to compose, flushing client target buffer.
2022-06-04 18:09:22.593 329-375/? W/RanchuHwc: validateDisplay: layer 90 CompositionType 1, fallback
2022-06-04 18:09:22.597 329-375/? W/RanchuHwc: presentDisplay display has no layers to compose, flushing client target buffer.
2022-06-04 18:09:22.608 329-375/? W/RanchuHwc: validateDisplay: layer 90 CompositionType 1, fallback
2022-06-04 18:09:22.613 329-375/? W/RanchuHwc: presentDisplay display has no layers to compose, flushing client target buffer.
2022-06-04 18:09:22.624 329-375/? W/RanchuHwc: validateDisplay: layer 90 CompositionType 1, fallback
2022-06-04 18:09:22.630 329-375/? W/RanchuHwc: presentDisplay display has no layers to compose, flushing client target buffer.
2022-06-04 18:09:22.651 738-738/? D/StatusBar: disable<e i a s b h r c s > disable2<q i n >
2022-06-04 18:09:22.685 738-906/? D/EGL_emulation: app_time_stats: avg=593.46ms min=21.09ms max=3280.81ms count=7
2022-06-04 18:09:22.855 738-738/? D/StatusBar: disable<e i a s b h r c s > disable2<q i n >
2022-06-04 18:09:32.346 315-7718/? W/android.hardware.audio@6.0-impl.ranchu: TinyalsaSink::consumeThread:179 pcm_write failed with res=-1
2022-06-04 18:09:36.345 1748-1748/? D/BoundBrokerSvc: onUnbind: Intent { act=com.google.android.gms.feedback.internal.IFeedbackService dat=chimera-action:com.google.android.gms.feedback.internal.IFeedbackService cmp=com.google.android.gms/.chimera.GmsBoundBrokerService }

@helenaford helenaford changed the title [targetSdkVersion 31] notifee.onBackgroundEvent get called once when the notification displayed but not when action get pressed! Android: onBackgroundEvent not fired when action is pressed Jun 12, 2022
@trentlarson
Copy link

+1 on this issue

@notifee/react-native 5.3.0
react-native 0.63.4

Running on MacOS, on Android emulator Pixel_XL_API_30

I don't get any indication that the notification got pressed. Other things (getInitiialNotification & onForeGroundEvent) work when it's in other states, but when it's in the background a press on the notification just brings up the app and the AppState switches, but I can't find any way to determine that a notification press just happened. (Will accept workarounds!) (It doesn't trigger on iOS, either, but the onForegroundEvent works fine there.)

@jared-94
Copy link

jared-94 commented Aug 9, 2022

+1

When app is killed, onBackgroundEvent is never called on press action (Android 11 & 12).

Downgrading targetSDK to 30 "solves" the problem for me (RN 0.68.2)

@sosunny
Copy link

sosunny commented Aug 10, 2022

+1
Downgrading targetSDK solves it, but Playstore requires new apps to be built with SDK 31 so this is not a solution for us :/
And indeed onBackgroundEvent only has an issue with "ACTION_PRESS" events, so for now we just won't be able to use that feature :'(

@mikehardy my logcat output seems pretty similar to @fabyeah 's above. Do you mind sharing if there's any plans to address this issue?

@dcosmin2003
Copy link

Hello, we can't downgrade targetSdk to 30, because Play Store is not accepting it. What other workarounds do we have?

@mieszko4
Copy link
Contributor

mieszko4 commented Nov 28, 2022

My case:
"@notifee/react-native": "5.7.0",, "react-native": "0.64.4",, Android 12, targetSdkVersion = 31

App is in QUIT state. I create a push with action after getting high priority remote data push.
onBackgroundEvent is triggered when push is delivered (EventType=DELIVERED, headless=true).
onForegroundEvent is triggered when push action is tapped (EventType=ACTION_PRESS, headless=undefined) BUT ONLY if I register onForegroundEvent directly in index.js

Since AppRegistry.registerComponent registers a component that does not run in headless mode, it looks like event actually comes in headless mode but is wrongly interpreted as foreground.

Obviously registering onForegroundEvent directly in index.js is not correct since I cannot clean up listeners.
Android 5 correctly uses onBackgroundEvent.

@mieszko4
Copy link
Contributor

onForegroundEvent is triggered when push action is tapped (EventType=ACTION_PRESS, headless=undefined) BUT ONLY if I register onForegroundEvent directly in index.js

I am wondering why headless key is missing from Event in this case. In react-native/android/src/main/java/io/invertase/notifee/NotifeeEventSubscriber.java it is always set to either TRUE or FALSE...

@mieszko4
Copy link
Contributor

mieszko4 commented Nov 28, 2022

Looks like isAppInForeground returns true when it should return false, i.e. after hardcoding return false in isAppInForeground I receive the event ACTION_PRESS in onBackgroundEvent as expected.

Other option is that react-native (0.64.4) is wrong when deciding if app is in foreground. Never mind, I see that isAppInForeground uses reactContext.getLifecycleState()

@mieszko4
Copy link
Contributor

mieszko4 commented Nov 28, 2022

Looks like isAppInForeground returns true when it should return false, i.e. after hardcoding return false in isAppInForeground I receive the event ACTION_PRESS in onBackgroundEvent as expected.

It is returning true because of ClassCastException exception. Not sure if that's expected logic or an actual exception which should never happen.

java.lang.ClassCastException: [...].MainApplication cannot be cast to com.facebook.react.bridge.ReactContext

@venux92
Copy link

venux92 commented Nov 28, 2022

@mieszko4 I can confirm, I just tested

try {
  reactContext = (ReactContext) context;
} catch (ClassCastException exception) {
  return false; // <== forced to false
}

Returning false in the ClassCastException on "@notifee/react-native": "7.1.0" on Android 12 and 13 is working correctly, the onBackgroundEvent gets correctly fired when I tap on the press action ACTION_PRESS

Unfortunately this is not a solution, but posting it here just to confirm it.

Really appreciated your research 👍🏽

@mieszko4
Copy link
Contributor

@venux92 Which version of react-native do you use?

🤔 I wonder if that's related to incompatibility of react-native and targetSDKVersion=31. In v0.68.0 targetSDKVersion was changed to 31. So maybe upgrading react-native to 0.68.0 will fix this...

@dcosmin2003
Copy link

@venux92 Which version of react-native do you use?

🤔 I wonder if that's related to incompatibility of react-native and targetSDKVersion=31. In v0.68.0 targetSDKVersion was changed to 31. So maybe upgrading react-native to 0.68.0 will fix this...

I'm using react native 0.68.4 and targetSDK 33 and it's not fixed.

@mikehardy
Copy link
Contributor

A suggestion: everyone upgrade to current stable versions of software then try reproducing? That's a best practice, ends up saving more time then the apparent "possibly wasted time" of updating to current stable, in my experience

@amjadbouhouch
Copy link
Author

@mikehardy Thank you for the suggestion, I'll give it a try right now, because today our app was rejected by google it requires TargetSdkVersion = 31 minimum.

@mieszko4
Copy link
Contributor

A suggestion: everyone upgrade to current stable versions of software then try reproducing?

@mikehardy What do you mean by current stable versions? Isn't @notifee/react-native@5.7.0 and react-native@0.68.4 stable?

@mikehardy
Copy link
Contributor

mikehardy commented Nov 28, 2022

stable but not current

current stable is react-native 0.70.6, @notifee/react-native 7.1.0

https://github.com/invertase/notifee/releases

So no, neither are current and stable and you have a high probability of chasing phantom issues that are already fixed, and you're requesting others attention for the same, potentially spending everyone's time inefficiently.

@mieszko4
Copy link
Contributor

current stable is react-native 0.70.6, @notifee/react-native 7.1.0

https://github.com/invertase/notifee/releases

So no, neither are current and stable and you have a high probability of chasing phantom issues that are already fixed, and you're requesting others attention for the same, potentially spending everyone's time inefficiently.

Right, I agree. Just the problem is that there are breaking changes in react-native and associated packages so it is not straightforward to upgrade to the current stable versions (at least in my case).

@amjadbouhouch
Copy link
Author

@mieszko4 I have "react-native": "^0.67.5" and "@notifee/react-native": "7.1.0", . I'm not sure I can now upgrade to react-native 70.6., there are breaking changes and new architecture https://react-native-community.github.io/upgrade-helper/?from=0.67.5&to=0.70.6

I also I can confirm with @venux92 This is working for me.

try {
  reactContext = (ReactContext) context;
} catch (ClassCastException exception) {
  return false; // <== forced to false
}

Can I use this in production like a temporary solution until I upgrade to react-native@0.70.6 ?

@mikehardy
Copy link
Contributor

New Architecture is orthogonal. You don't have to use it. It is an option. Stated more directly: react-native-firebase does not even support New Architecture at all! Yet, you may use react-native-firebase with react-native 0.70.6 without problem https://github.com/mikehardy/rnfbdemo/blob/main/make-demo.sh

There is no reason not to update to current stable versions prior to requesting other people's time investigating help on problems that may already be fixed.

@mikehardy
Copy link
Contributor

At the same time, open source is amazing - you've got all the source and if you've got some solution that works for you, use it! https://github.com/ds300/patch-package is something I use frequently myself.

Though I typically use it only temporarily while I'm already on current stable versions and I'm working a PR through the upstream package....

@amjadbouhouch
Copy link
Author

@mikehardy thank you again for your guidance and support.
https://github.com/ds300/patch-package This is definitely what I'm looking for.

@mieszko4
Copy link
Contributor

mieszko4 commented Nov 28, 2022

Just wanted to share my findings.

On Android 5 appProcess.importance is never IMPORTANCE_FOREGROUND in background state hence isAppInForeground returns false. And on frontend state isAppInForeground always throws hence it returns true.
On Android 12 appProcess.importance is IMPORTANCE_FOREGROUND after push is tapped hence it throws and returns true. I am not sure why it returns IMPORTANCE_FOREGROUND in case only push is visible - looks like ActivityManager.RunningAppProcessInfo is not reliable to be used here.

My point is the current implementation of isAppInForeground will always throw when condition in the loop is satisfied because it casts to ReactContext, wheres it should cast to ReactApplication like it is done in getReactContext. So that seems like a bug that did not have a chance to be noticed :)

This patch fixes that bug. However, it now makes Android 12 show taps as headless when app is opened because reactContext.getLifecycleState() is BEFORE_RESUME when push is visible:

diff --git a/packages/react-native/android/src/main/java/io/invertase/notifee/NotifeeReactUtils.java b/packages/react-native/android/src/main/java/io/invertase/notifee/NotifeeReactUtils.java
index b60e6d4..805447c 100644
--- a/packages/react-native/android/src/main/java/io/invertase/notifee/NotifeeReactUtils.java
+++ b/packages/react-native/android/src/main/java/io/invertase/notifee/NotifeeReactUtils.java
@@ -210,12 +210,9 @@ class NotifeeReactUtils {
     for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
       if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
           && appProcess.processName.equals(packageName)) {
-        ReactContext reactContext;
-
-        try {
-          reactContext = (ReactContext) context;
-        } catch (ClassCastException exception) {
-          return true;
+        ReactContext reactContext = getReactContext();
+        if (reactContext == null) {
+          return false;
         }
 
         return reactContext.getLifecycleState() == LifecycleState.RESUMED;

If I find some time I will check if this is an issue with current stable versions.

@mieszko4
Copy link
Contributor

mieszko4 commented Nov 28, 2022

If I find some time I will check if this is an issue with current stable versions.

I started fresh (https://reactnative.dev/docs/environment-setup) using react-native": "0.70.6, keeping newArchEnabled=false and with compileSdkVersion = 33 and installing latest @notifee/react-native@7.1.0 with basic snippet from https://notifee.app/react-native/docs/displaying-a-notification:

function Screen() {
  async function onDisplayNotification() {
    // Request permissions (required for iOS)
    await notifee.requestPermission()

    // Create a channel (required for Android)
    const channelId = await notifee.createChannel({
      id: 'default',
      name: 'Default Channel',
    });

    // Display a notification
    await notifee.displayNotification({
      title: 'Notification Title',
      body: 'Main body content of the notification',
      android: {
        channelId,
        //smallIcon: 'name-of-a-small-icon', // optional, defaults to 'ic_launcher'.
        // pressAction is needed if you want the notification to open the app when pressed
        pressAction: {
          id: 'default',
        },
      },
    });
  }

  return (
    <View>
      <Button title="Display Notification" onPress={() => onDisplayNotification()} />
    </View>
  );
}

And I added Log.e("ERROR", "", exception); in catch of isAppInForeground defined in react-native/android/src/main/java/io/invertase/notifee/NotifeeReactUtils.java
Finally I rebuild the app using yarn android.

On Android 12, after tapping on Display Notification I get ERROR msg. After tapping on the push I also get ERROR msg.

I cannot see the point of this try/catch if it always throws and makes isAppInForeground to return true :)

@mieszko4
Copy link
Contributor

Also, isAppInForeground returns true for me after closing the app and tapping on notification - tested on Android 12 (LG) and Android 13 (Samsung).

@jared-94
Copy link

jared-94 commented Dec 1, 2022

@mieszko4
The problem is not with pressAction but with Quick Actions (thus actions object).

With the following setup :

  • RN 0.70.6
  • targetSDK = 33
  • Notifee 7.1.0
  • Android 12 or 13

Passing quick actions to notifee.displayNotification, then notifee.onBackgroundEvent is NEVER called when app is killed and user tap an action.

I think this problem should be considered as critical by the Notifee Team

@mikehardy
Copy link
Contributor

mikehardy commented Dec 1, 2022

I think this problem should be considered as critical by the Notifee Team

With apologies - just to set expectations, considering it critical or not does not magically make more hours appear in the day. It's an open source project, and all reasonable PRs will be merged + released.

If this is something that affects your business, it may be worth it for you to prioritize development resources to investigate + fix

@mieszko4
Copy link
Contributor

mieszko4 commented Dec 1, 2022

The problem is not with pressAction but with Quick Actions (thus actions object).

Yes, the issue for me was also with Quick Actions. With #404 (comment) I just wanted to show the smallest reproducible code which is the cause of this issue. On the project, I am using the patch that I provided in that comment and it's been working great for me.

@jared-94
Copy link

jared-94 commented Dec 2, 2022

With apologies - just to set expectations, considering it critical or not does not magically make more hours appear in the day. It's an open source project, and all reasonable PRs will be merged + released.

If this is something that affects your business, it may be worth it for you to prioritize development resources to investigate + fix

I am sorry if I have been offensive.
I know it's open source but unfortunately, I'm not very good at JAVA.
I do not have any business and write code only for fun ! (probably you too)

@mikehardy
Copy link
Contributor

Not offensive - no worries - just wanted to make sure expectations were aligned.

I maintain react-native repositories on contract and have a startup that's taking off right now, I write code for money, though I do enjoy it. I never have enough time in the day though, and don't personally have time for this one right now

@helenaford
Copy link
Member

helenaford commented Dec 5, 2022

Massive thanks to @mieszko4 for fixing this issue! Released in 7.2.0

@helenaford helenaford changed the title Android: onBackgroundEvent not fired when action is pressed Android: onBackgroundEvent not fired when quick action is pressed Dec 5, 2022
@jino-peak
Copy link

jino-peak commented Dec 12, 2022

I was facing this issue after updating to TargetSdkVersion = 31 in 5.x.x of Notifee.
Now I have updated Notifee to 7.2.0 and set TargetSdkVersion to 33.
The issue with quick action press is fixed in Android 11 devices.
But I can still reproduce the issue in Android 12 devices

*** Issue is observed in VIVO phones. I will check other devices and update here if issue is present in other devices

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.