expo: addNotificationResponseReceivedListener is not working when app is opened from killed state

Summary

I have followed the example provided from Expo notification module to setup local push notifications. The notification linking works as expected if the app is in the background, but if the app is opened from killed state the addNotificationResponseReceivedListener is not fired as referred in developer documentation.

Managed or bare workflow? If you have ios/ or android/ directories in your project, the answer is bare!

managed

What platform(s) does this occur on?

Android

SDK Version (managed workflow only)

44

Environment

expo-env-info 1.0.5 environment info: System: OS: macOS 10.15.7 Shell: 5.7.1 - /bin/zsh Binaries: Node: 14.19.1 - ~/.nvm/versions/node/v14.19.1/bin/node npm: 6.14.16 - ~/.nvm/versions/node/v14.19.1/bin/npm SDKs: iOS SDK: Platforms: iOS 13.7, DriverKit 19.0, macOS 10.15, tvOS 13.4, watchOS 6.2 IDEs: Xcode: 11.7/11E801a - /usr/bin/xcodebuild npmPackages: expo: ~44.0.0 => 44.0.6 react: 17.0.1 => 17.0.1 react-dom: 17.0.1 => 17.0.1 react-native: 0.64.3 => 0.64.3 react-native-web: 0.17.1 => 0.17.1 Expo Workflow: managed

Reproducible demo

const triggerNotification = () => {
 
  Notifications.scheduleNotificationAsync({
    content: {
      title: "Notification title",
      body: `Some body content`,
      data: { name: "Joe", age: "24" },
    },
    trigger: {
      seconds: 60,
      repeats: true,
    },
  });
};



useEffect(() => {
    registerForPushNotificationsAsync().then((token) =>
      setExpoPushToken(token)
    );

    notificationListener.current =
      Notifications.addNotificationReceivedListener((notification) => {
        setNotification(notification);
      });

    responseListener.current =
      Notifications.addNotificationResponseReceivedListener((response) => {
        console.log(response);
      });

   
     triggerNotification();
  
    return () => {
      Notifications.removeNotificationSubscription(
        notificationListener.current
      );
      Notifications.removeNotificationSubscription(responseListener.current);
    };
  }, []);

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 21 (1 by maintainers)

Most upvoted comments

This should be kept open as it used to work regardless of where the listener is created. Currently useLastNotificationResponse will not work on Android from killed state regardless of where it’s used. addNotificationResponseReceivedListener can work (we have it working in production on Android with Expo 46 as do others), but ONLY if the listener is created extremely early in the application – BEFORE and outside any React component functions/classes. The notification touch event then has to be retained so later code can use it.

Same issue here. I tried multiple things (including putting useLastNotificationResponse and addNotificationResponseReceivedListener at the top of the chain) and nothing seems to work. On Android standalone when app is killed it will never fire these…

There are more people, this particular issue is just a duplicate that’s been closed. Check out https://github.com/expo/expo/issues/14078

While there is definitely a bug, some of us have worked around it successfully by implementing a listener very early in the code to capture the event to be processed later. (as you’ll see in that other issue) That still works for me in Expo 49, I haven’t tried 50 yet. However, it doesn’t seem to work for everyone as you’ll also see in that issue. Not sure why.

can’t believe not more people are facing this issue

This is on iOS 17.3, and SDK 49 never gets called, no matter what I do. Even when the app is foregrounded, nothing happens. When a user clicks on the badge/notification, it only brings the app to the foreground or remains on the screen you were on if the app was already in the foreground.

import * as Notifications from 'expo-notifications';
import { router } from 'expo-router';
import React from 'react';

export function useNotificationObserver() {
  React.useEffect(() => {
    let isMounted = true;

    function redirect(notification: Notifications.Notification) {
      console.log('notification', notification);
      const url = notification.request.content.data?.url;
      if (url) {
        router.push(url);
      }
    }

    Notifications.getLastNotificationResponseAsync().then((response) => {
        if (!isMounted || !response?.notification) {
          return;
        }
      console.log(response, 'response crapssssss');
        redirect(response?.notification);
    });

    const subscription = Notifications.addNotificationResponseReceivedListener(
      (response) => {
        console.log('notification response received', response);
        redirect(response.notification);
      },
    );

    return () => {
      isMounted = false;
      subscription.remove();
    };
  }, []);
}

I am using expo-router

@kartikk221 I’m still in Expo 46. Waiting on an SVG library bug in 47 to get resolved before moving. Although it sounds like that may have been resolved, in which case I’ll probably try things in a couple weeks. (on another project at the moment).

I am having this same issue even if the app is in background or killed state with FCM notifications. Foregrounded app works as expected.