ionic-team / capacitor

Build cross-platform Native Progressive Web Apps for iOS, Android, and the Web āš”ļø
https://capacitorjs.com
MIT License
11.45k stars 977 forks source link

bug: PushNotifications registration on IOS doesn't return APNs token #4687

Closed qliqdev closed 3 years ago

qliqdev commented 3 years ago

Bug Report

Hi everyone! Unable to receive APNs token from listener; Using latest Capacitor; I've done every thing from these docs:

  1. https://capacitorjs.com/docs/apis/push-notifications
  2. https://capacitorjs.com/docs/v3/guides/push-notifications-firebase

iOS: 14.6 Iphone 12 Mini

Capacitor Version

  @capacitor/cli: 3.0.0
  @capacitor/android: 3.0.0
  @capacitor/ios: 3.0.0
  @capacitor/core: 3.0.0

Platform(s)

ios

Current Behavior

PushNotifications register called But nothing returned

Expected Behavior

Expecting APNs token

Code Reproduction

    PushNotifications.addListener('registration',
      (token: PushNotificationToken) => {
        alert('Push registration success, token: ' + token.value);
      }
    );

    PushNotifications.requestPermissions().then(result => {
        if (result.receive === 'granted') {
          PushNotifications.register();
        }
    });

Podfile

platform :ios, '12.0'
use_frameworks!

# workaround to avoid Xcode caching of Pods that requires
# Product -> Clean Build Folder after new Cordova plugins installed
# Requires CocoaPods 1.6 or newer
install! 'cocoapods', :disable_input_output_paths => true

def capacitor_pods
  pod 'Capacitor', :path => '../../node_modules/@capacitor/ios'
  pod 'CapacitorCordova', :path => '../../node_modules/@capacitor/ios'
  pod 'CapacitorCommunityContacts', :path => '../../node_modules/@capacitor-community/contacts'
  pod 'CapacitorApp', :path => '../../node_modules/@capacitor/app'
  pod 'CapacitorBrowser', :path => '../../node_modules/@capacitor/browser'
  pod 'CapacitorCamera', :path => '../../node_modules/@capacitor/camera'
  pod 'CapacitorClipboard', :path => '../../node_modules/@capacitor/clipboard'
  pod 'CapacitorDevice', :path => '../../node_modules/@capacitor/device'
  pod 'CapacitorGeolocation', :path => '../../node_modules/@capacitor/geolocation'
  pod 'CapacitorHaptics', :path => '../../node_modules/@capacitor/haptics'
  pod 'CapacitorKeyboard', :path => '../../node_modules/@capacitor/keyboard'
  pod 'CapacitorPushNotifications', :path => '../../node_modules/@capacitor/push-notifications'
  pod 'CapacitorShare', :path => '../../node_modules/@capacitor/share'
  pod 'CapacitorSplashScreen', :path => '../../node_modules/@capacitor/splash-screen'
  pod 'CapacitorStatusBar', :path => '../../node_modules/@capacitor/status-bar'
  pod 'CapacitorStorage', :path => '../../node_modules/@capacitor/storage'
  pod 'CapacitorTextZoom', :path => '../../node_modules/@capacitor/text-zoom'
  pod 'CapacitorToast', :path => '../../node_modules/@capacitor/toast'
  pod 'CapacitorNativeBiometric', :path => '../../node_modules/capacitor-native-biometric'
  pod 'CordovaPlugins', :path => '../capacitor-cordova-ios-plugins'
  pod 'CordovaPluginsResources', :path => '../capacitor-cordova-ios-plugins'
end

target 'App' do
  capacitor_pods
  # Add your Pods here
  pod 'Firebase/Messaging'
end

AppDelegate.swift

import UIKit
import Capacitor
import Firebase
import FirebaseMessaging
import NotificationCenter

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        FirebaseApp.configure()
        return true
    }

    func applicationWillResignActive(_ application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

    func applicationWillTerminate(_ application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }

    func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
        // Called when the app was launched with a url. Feel free to add additional processing here,
        // but if you want the App API to support tracking app url opens, make sure to keep this call
        return ApplicationDelegateProxy.shared.application(app, open: url, options: options)
    }

    func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
        // Called when the app was launched with an activity, including Universal Links.
        // Feel free to add additional processing here, but if you want the App API to support
        // tracking app url opens, make sure to keep this call
        return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesBegan(touches, with: event)

        let statusBarRect = UIApplication.shared.statusBarFrame
        guard let touchPoint = event?.allTouches?.first?.location(in: self.window) else { return }

        if statusBarRect.contains(touchPoint) {
            NotificationCenter.default.post(name: .capacitorStatusBarTapped, object: nil)
        }
    }

    #if USE_PUSH

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Messaging.messaging().apnsToken = deviceToken
        Messaging.messaging().token(completion: { (token, error) in
            if let error = error {
                NotificationCenter.default.post(name: .capacitorDidFailToRegisterForRemoteNotifications, object: error)
            } else if let token = token {
                NotificationCenter.default.post(name: .capacitorDidRegisterForRemoteNotifications, object: token)
            }
        })
    }

    #endif

}

Also tried

#if USE_PUSH

    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
      NotificationCenter.default.post(name: .capacitorDidRegisterForRemoteNotifications, object: deviceToken)
    }

    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
      NotificationCenter.default.post(name: .capacitorDidFailToRegisterForRemoteNotifications, object: error)
    }

    #endif

Other Technical Details

npm --version output: 7.15.1

node --version output: v15.14.0

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

Additional Context

On Android works well. Also i generated all needed certificates in Apple Developer and uploaded to Firebase Messaging IOS configuration;

Guesses: May be APNs will be returned after publishing App to Appstore?

jcesarmobile commented 3 years ago

Remove the #if USE_PUSH macro lines, including the closing #endif (but not what's in between them), that's no longer needed, I don't see them in the links you posted, if you do, you probably have a cached version.

Also, note that you are using FCM, so you'll get the FCM token, not the APNs token. You don't really need to use FCM on iOS, that guide was created because a lot of people wanted to use it, but you can use push notifications with APNs directly or any other service (for other services you might need plugins)

qliqdev commented 3 years ago

Remove the #if USE_PUSH macro lines, including the closing #endif (but not what's in between them), that's no longer needed, I don't see them in the links you posted, if you do, you probably have a cached version.

Also, note that you are using FCM, so you'll get the FCM token, not the APNs token. You don't really need to use FCM on iOS, that guide was created because a lot of people wanted to use it, but you can use push notifications with APNs directly or any other service (for other services you might need plugins)

Thats incredible. Even didn't about that. Thank you very much. You saved my time

Saqib92 commented 2 years ago

Have Same Configuration and even tried the above mentioned solution still my Notifications are not working on IOS. I can see my FCM Token in Xcode Logs. Here is the Issue with Details:

šŸ’Š   Capacitor Doctor  šŸ’Š 

Latest Dependencies:

  @capacitor/cli: 3.2.2
  @capacitor/core: 3.2.2
  @capacitor/android: 3.2.2
  @capacitor/ios: 3.2.2

Installed Dependencies:

  @capacitor/cli: 3.2.2
  @capacitor/core: 3.2.2
  @capacitor/android: 3.2.2
  @capacitor/ios: 3.2.2

https://github.com/capacitor-community/fcm/issues/90#issue-987696998

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.