测试已发送FCM-PN,但未接收到云功能生成的推送通知(在Android上等效)

时间:2020-06-28 21:26:41

标签: ios swift firebase-cloud-messaging apn

我能够从Firebase控制台在前台和后台发送测试通知(应用程序处于休眠状态且已关闭)。但是没有接收到由云功能触发的推送通知。

enter image description here

我知道推送通知有效,因为该应用的Android版本可以接收它们。

这是我用来启用推送通知的教程(我自然排除了不推荐使用的功能):

https://code.tutsplus.com/tutorials/get-started-with-firebase-messaging-for-ios--cms-32126#comment-4345018783

https://www.iosapptemplates.com/blog/ios-development/push-notifications-firebase-swift-5

总结:

  • 已获得APN密钥,已上传到Firebase
  • 开启功能

enter image description here

  • 我从Google服务.plist文件中获取了REVERSED_CLIENT_ID,并将其粘贴为URL方案。我没有晕倒的线索,这是怎么回事,但它在this tutorialenter image description here

这是我的应用程序委托:

class AppDelegate: UIResponder, UIApplicationDelegate {
    
    let gcmMessageIDKey = "gcm.message_id"

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        FirebaseApp.configure()
        Messaging.messaging().delegate = self
        
        if #available(iOS 10.0, *) {
          // For iOS 10 display notification (sent via APNS)
          UNUserNotificationCenter.current().delegate = self

          let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
          UNUserNotificationCenter.current().requestAuthorization(
            options: authOptions,
            completionHandler: {_, _ in })
        } else {
          let settings: UIUserNotificationSettings =
          UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
          application.registerUserNotificationSettings(settings)
        }

        //get application instance ID
        InstanceID.instanceID().instanceID { (result, error) in
            if let error = error {
                print("Error fetching remote instance ID: \(error)")
            } else if let result = result {
                print("Remote instance ID token: \(result.token)")
            }
        }
        
        application.registerForRemoteNotifications()
        
        return true
    }

    // MARK: UISceneSession Lifecycle

    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }

    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
        // Called when the user discards a scene session.
        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
    }


}

extension AppDelegate : MessagingDelegate {
    
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
      // If you are receiving a notification message while your app is in the background,
      // this callback will not be fired till the user taps on the notification launching the application.
      // TODO: Handle data of notification

      // With swizzling disabled you must let Messaging know about the message, for Analytics
       //Messaging.messaging().appDidReceiveMessage(userInfo)

      // Print message ID.
      if let messageID = userInfo[gcmMessageIDKey] {
        print("Message ID: \(messageID)")
      }

      // Print full message.
      print(userInfo)
    }

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                     fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
      // If you are receiving a notification message while your app is in the background,
      // this callback will not be fired till the user taps on the notification launching the application.
      // TODO: Handle data of notification

      // With swizzling disabled you must let Messaging know about the message, for Analytics
      // Messaging.messaging().appDidReceiveMessage(userInfo)

      // Print message ID.
      if let messageID = userInfo[gcmMessageIDKey] {
        print("Message ID: \(messageID)")
      }

      // Print full message.
      print(userInfo)

      completionHandler(UIBackgroundFetchResult.newData)
    }
    
    func application(_ application: UIApplication, didRegiterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let tokenParts = deviceToken.map { //data -> String in
            return String(format: "%02.2hhx", $0)
        }
        print(tokenParts)

        Messaging.messaging().apnsToken = deviceToken
        Messaging.messaging().setAPNSToken(deviceToken, type: .unknown)
        UserDefaults.standard.synchronize()
    }
}

@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {
    
    // Receive displayed notifications for iOS 10 devices.
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        let userInfo = notification.request.content.userInfo
        
        // With swizzling disabled you must let Messaging know about the message, for Analytics
        // Messaging.messaging().appDidReceiveMessage(userInfo)
        
        // Print message ID.
        if let messageID = userInfo[gcmMessageIDKey] {
            print("Message ID: \(messageID)")
        }
        
        // Print full message.
        print(userInfo)
        
        // Change this to your preferred presentation option
        completionHandler([[.alert, .badge, .sound]])
    }
    
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        let userInfo = response.notification.request.content.userInfo
        // Print message ID.
        if let messageID = userInfo[gcmMessageIDKey] {
            print("Message ID: \(messageID)")
        }
        
        // Print full message.
        print(userInfo)
        
        completionHandler()
    }
}

我关闭了烦恼(我一生无法把握它的本质,但是根据Firebase,我应该将其关闭,就像我做到的那样。

enter image description here

值得一提的是,当我从AppDelegate推送令牌时,令牌并不总是保存在服务器上。由于我在应用程序中设置了侧面菜单,因此将其作为扩展放置在其中(也许稍后再进行更改,但是云功能必须具有最新的令牌):

extension ContainerViewController : MessagingDelegate {

    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
      print("Firebase registration token: \(fcmToken)")

      let dataDict:[String: String] = ["token": fcmToken]
      NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
      // TODO: If necessary send token to application server.
      // Note: This callback is fired at each app startup and whenever a new token is generated.
        let db = Firestore.firestore()
        getUserEmail { (userId) in
            if let userId = userId {
                let userRef = db.collection("Customer_Data").document(userId)
                userRef.setData(["tokenId" : fcmToken], merge : true)
            }
        }
    }
    
    func getUserEmail(completion : @escaping (String?) -> Void) {
        let user = Auth.auth().currentUser
        if let user = user?.email {
            completion(user)
        }
    }
}

因此我可以验证令牌是否已保存。这时我可能做错了什么?是的,这是在Mac上插入的物理设备上,并且在无线推送构建时。

编辑 添加了APNs身份验证密钥而不是证书

两个通知的有效载荷

data: {
                title: notificationTypes[notificationType].title + ' ' + planType ,
                body:  'Meal Plan: ' + order.mpName +  '\n' + 
                        'Restaurant:' + order.restaurantName + '\n' + 
                        'Total sum :' + order.currentTotal,
            }

data : {
              title: notificationTypes[notificationType].title + ' ' + planType ,
              body:  'Meal Plan: ' + order.mpName +  '\n' + 
                     'Restaurant:' + order.restaurantName + '\n' + 
                     'Total sum :' + order.currentTotal,
              color:'#3EDF3E',
              tag: notificationTypes[notificationType].tag
          }

enter image description here

0 个答案:

没有答案