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

PRESS event is not detected in onBackgroundEvent #1105

Open
tamirla opened this issue Sep 22, 2024 · 8 comments
Open

PRESS event is not detected in onBackgroundEvent #1105

tamirla opened this issue Sep 22, 2024 · 8 comments

Comments

@tamirla
Copy link

tamirla commented Sep 22, 2024

I'm using notifee to send local notification from inside the app and want to be able to detect that user pressed on notification.

I thought I will be able to check for PRESS event type inside onBackgroundEvent, however I noticed that onBackgroundEvent is triggered only once with DELIVERED event type, then the app is opened, and only then I can detect PRESS event type inside onForegroundEvent that is triggered once the app is opened.

my questions are -

  • Is this the expected behaviour ?
  • shouldn't onBackgroundEvent be able to use also to detect PRESS event ?
  • Is it possible that onBackgroundEvent will be triggered multiple times, first with DELIVERED, then with PRESS ?
  • If not, how else it can detect PRESS if it was already triggered with DELIVERED ?

I found the following "hint" that implies I should use onForegroundEvent but I didn't really understand why...

I'm using only notifee without Firebase, most examples & issues I saw involve also Firebase.

In iOS I at least get both onBackgroundEvent & onForegroundEvent triggered, in Android I'm seeing only onBackgroundEvent triggered once with DELIVERED and don't see onForegroundEvent triggered at all.

I thought this could be related to this issue, however I'm using RN < 0.73:

"react-native": "0.72.10"
"@notifee/react-native": "^7.8.2",

Just to clarify - I want to detect when user pressed on notification itself, I don't have any buttons on the notification.

@vkukade-altir
Copy link

vkukade-altir commented Sep 22, 2024

Same issue for me.
"react-native": "0.72.4",
"@notifee/react-native": "9.0.0",
Android version : 14 (API level 34)

On android, notifee's onBackgroundEvent and even getInitialNotification doesn't fire if user click on notification. I have already added following in index.js file.

messaging().setBackgroundMessageHandler(async remoteMessage => {
console.log('Message handled in the background!', remoteMessage);
});

I even tried what he says in this comment. #616 (comment)
But still not working for Android.

My use case is: that I want to support both local and remote push notifications.

What I have tried:

If I use the standalone package https://github.com/wix/react-native-notifications only for remote push notifications -> This works fine in all cases for Android and IOS. But this doesn't support android local notifications.

If I use Notifee package version 5.7.0 and use Firebase functions (getInitialNotification, onNotificationOpenedApp) this also works good for remote notifications and local notifications. But here still notification tap doesn't work

If I try to use notifee version 9.0.0 above mentioned issue occurs.

@Eclipses-Saros
Copy link

this is what I wanted to find why: android events are not working as expected.
I didn't find the reason yet, but I can share some information you might help.

const apiModule = new NotifeeApiModule_1.default({
    version: version_1.version,
    nativeModuleName: 'NotifeeApiModule',
    nativeEvents: utils_1.isIOS
        ? [utils_1.kReactNativeNotifeeNotificationEvent, utils_1.kReactNativeNotifeeNotificationBackgroundEvent]
        : [utils_1.kReactNativeNotifeeNotificationEvent],
});

first, notifee registers nativeEvents to receive events. remember the event name: kReactNativeNotifeeNotificationEvent.

export const kReactNativeNotifeeNotificationEvent = 'app.notifee.notification-event';

second, initialize module based on NotifeeApiModule.java (create method to connect native module). you can find some platform specific workaround.

class NotifeeApiModule extends NotifeeNativeModule_1.default {
    constructor(config) {
        super(config);
        if (utils_1.isAndroid) {
            // Register background handler
            react_native_1.AppRegistry.registerHeadlessTask(utils_1.kReactNativeNotifeeNotificationEvent, () => {
                return (event) => {
                    if (!backgroundEventHandler) {
                        console.warn('[notifee] no background event handler has been set. Set a handler via the "onBackgroundEvent" method.');
                        return Promise.resolve();
                    }
                    return backgroundEventHandler(event);
                };
            });
        }
        else if (utils_1.isIOS) {
            this.emitter.addListener(utils_1.kReactNativeNotifeeNotificationBackgroundEvent, (event) => {
                if (!backgroundEventHandler) {
                    console.warn('[notifee] no background event handler has been set. Set a handler via the "onBackgroundEvent" method.');
                    return Promise.resolve();
                }
                return backgroundEventHandler(event);
            });
        }
    }
    ...
    onForegroundEvent = (observer) => {
        if (!(0, utils_1.isFunction)(observer)) {
            throw new Error("notifee.onForegroundEvent(*) 'observer' expected a function.");
        }
        const subscriber = this.emitter.addListener(utils_1.kReactNativeNotifeeNotificationEvent, 
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-ignore See https://github.com/facebook/react-native/pull/36462
        ({ type, detail }) => {
            observer({ type, detail });
        });
        return () => {
            subscriber.remove();
        };
    };
    ...

as you can see, Android event listener uses same key, kReactNativeNotifeeNotificationEvent. the only difference is, foreground is using emitter.addListener, while background is AppRegistry.registerHeadlessTask.

public void onNotificationEvent(NotificationEvent notificationEvent) {
    ....
    if (isAppInForeground()) {
      eventMap.putBoolean(KEY_HEADLESS, false);
      NotifeeReactUtils.sendEvent(NOTIFICATION_EVENT_KEY, eventMap);
    } else {
      eventMap.putBoolean(KEY_HEADLESS, true);
      NotifeeReactUtils.startHeadlessTask(NOTIFICATION_EVENT_KEY, eventMap, 60000, null);
    }
    ....
}

onNotificationEvent called when you have some notification events, such as delivered, press.
and check app is foreground or not, module send event with sendEvent or startHeadlessTask.

to sum up, Android uses same event key, and native module calls different function whether foreground or not.
that's the how logic works. let's back to the question what you've asked:

Is this the expected behaviour ?

yes, and no. (as far as I've researched)

the only point checking foreground status is there. isAppInForeground() function. and what that means, if the function returns true, it always works as foreground. in reverse, yes background as well.
you expected pressing notification from background should be call background event, but it's not. isAppInForeground() says you're in foreground, so onForegroundEvent called.

expected: (pressing notification from background) -> detected as background and calls startHeadlessTask -> show events at onBackgroundEvent -> app shows up
reality: (pressing notification from background) -> app shows up -> detected as foreground and calls sendEvent -> show events at onForegroundEvent

shouldn't onBackgroundEvent be able to use also to detect PRESS event ?

I also remember that feature, when I was using 5.7.0 before. but years later... it just disappeared!
(well, I can merely guess there are tons of things changed after Android 12 (and 13, 14!), notifee has no option but following up these changes.)

Is it possible that onBackgroundEvent will be triggered multiple times, first with DELIVERED, then with PRESS? If not, how else it can detect PRESS if it was already triggered with DELIVERED ?

If you can fix logic, yes. there is no data difference between foreground and background.

Android I'm seeing only onBackgroundEvent triggered once with DELIVERED and don't see onForegroundEvent triggered at all.

if "triggered at all" means no events shows up, you need to check reactContext. I've said bug can occur RN >0.73, but there are no guarantee not to happened when you avoid it.

@shonie2xx
Copy link

"react-native": "^0.72.5"

For me, onBackgroundEvent works as expected on Android. However, on iOS, I only receive the TRIGGER_NOTIFICATION_CREATED event, any other events are not being registered.

export const remindersAnalytics = () => {
  const eventTypeMapping = {
    [EventType.PRESS]: 'clicked',
    [EventType.DISMISSED]: 'closed',
    [EventType.DELIVERED]: 'sent',
  };

  notifee.onBackgroundEvent(async ({ type, detail }) => {
    const target = eventTypeMapping[type];

    if (target) {
      logEvent('push_notification', {
        type: detail?.notification?.data?.type,
        target,
      });
    }
  });
};

@saadlatif75
Copy link

Any update?

@LunatiqueCoder
Copy link

@kabitacode
Copy link

same issue, is there any update for this case?

@saadlatif75
Copy link

saadlatif75 commented Nov 15, 2024 via email

@Dimon70007
Copy link

Dimon70007 commented Dec 11, 2024

hi guys.
on android 14+ we calling notifee.displayNotification with asForegroundService: false because of android restrictions,
we call method notifee.onBackgroundEvent(notifeeBackgroundEventHandler) in index.js,
we listen EventType.ACTION_PRESS in notifeeBackgroundEventHandler to handle user chose

when notification has displayed first time after app start then notifeeBackgroundEventHandler calls as expected
when notification has displayed second time after app start then notifeeBackgroundEventHandler does not call anymore

I think, there is missed part in documentation about notifee.onBackgroundEvent

  • notifee.onBackgroundEvent should be called in index.js for the first time start,
  • notifee.onBackgroundEvent should be called when application moved to background for receiving events in background also
    have added this code in App.tsx
  useEffect(() => {
    if (appState === 'background') {
      notifee.onBackgroundEvent(notifeeBackgroundEventHandler)
    }
    }, [appState])

it has fixed calling notifeeBackgroundEventHandler in background when user pressed on notification
You are Wellcome

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

No branches or pull requests

8 participants