ionic-team / capacitor

Build cross-platform Native Progressive Web Apps for iOS, Android, and the Web ⚡️
https://capacitorjs.com
MIT License
11.44k stars 977 forks source link

bug: pushNotificationReceived not call when app is in foreground. #4784

Closed mrkelvinli closed 3 years ago

mrkelvinli commented 3 years ago

Bug Report

Capacitor Version

💊   Capacitor Doctor  💊

Latest Dependencies:

  @capacitor/cli: 3.0.2
  @capacitor/core: 3.0.2
  @capacitor/android: 3.0.2
  @capacitor/electron: 3.0.2
  @capacitor/ios: 3.0.2

Installed Dependencies:

  @capacitor/cli 2.4.2
  @capacitor/android 2.4.2
  @capacitor/ios 2.4.2
  @capacitor/core 2.4.2
  @capacitor/electron not installed

Platform(s)

iOS

Current Behavior

Not receiving pushNotificationReceived event when the iOS app is in foreground. However, I got pushNotificationReceived events on Android when there is a new incoming push notification.

I am having this issue on my iPhone 12 with iOS 14.4.1

Expected Behavior

Receive a pushNotificationReceived event whenever the app receives a push notification.

Code Reproduction

PushNotifications.requestPermission().then(res => {
  if (res.granted) {
    console.log('calling register');
    return PushNotifications.register();
  }
});

PushNotifications.addListener(
  'pushNotificationReceived',
  notification => {
    console.log(notification);
  }
);

Other Technical Details

npm --version output: 6.14.10

node --version output: v14.15.4

pod --version output (iOS issues only): 1.10.1

There is a similar issue #4145 but it is for when the app is in background.

Additional Context

I looked into the PushNotifications plugin implementation in Swift and realised that if we reset the UserNotificationCenter.delegate after the permission was granted, then every started working again. I couldn't justify why this works, but it works. Any thoughts?

Reference: https://www.raywenderlich.com/books/push-notifications-by-tutorials/v2.0/chapters/8-handling-common-scenarios

node_modules/@capacitor/ios/Capacitor/Capacitor/CAPUNUserNotificationCenterDelegate.swift

public func requestPermissions(with completion: ((Bool, Error?) -> Void)? = nil) {
  let center = UNUserNotificationCenter.current()
  center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
    /**
     * It happens that the two delegate functions (`userNotificationCenter`) doesn't get
     * triggered if we set the UNUserNotificationCenter delegate before the user responses
     * to the permission request. Hence, we set the delegate again when the user granted
     * the notification permission.
     */
     if granted {
       center.delegate = self
     }

     completion?(granted, error)
  }
}
mrkelvinli commented 3 years ago

We seems to have re-implement the push notification plugin in Capacitor 3.0 (in NotificationRouter.swift). Not sure if this is still an issue in version 3?

jcesarmobile commented 3 years ago

I can't reproduce on Capacitor 3, so might be fixed. If you upgrade to Capacitor 3 and still face the issue, please, report it on https://github.com/ionic-team/capacitor-plugins/issues

richso commented 2 years ago

For those who have used the cordova-plugin-local-notification and @ionic-native/local-notifications, you may encounter this same problem in Capacitor3; please remove all references to these plugins, completely "npm remove" the packages and change to use @capacitor/local-notifications instead

ionitron-bot[bot] commented 1 year ago

Thanks for the issue! This issue is being locked to prevent comments that are not relevant to the original issue. If this is still an issue with the latest version of Capacitor, please create a new issue and ensure the template is fully filled out.