FIRMessagingDelegate's-messaging:didReceiveMessage: not implemented - Firebase 4.1.1 - Swift 3 - firebase

I upgraded Firebase from v3 to v4 but I have some problems in receiving messages and I get this warning:
[Firebase/Messaging][I-FCM002019] FIRMessaging received data-message, but FIRMessagingDelegate's-messaging:didReceiveMessage: not implemented
I know I should implement this method :
public func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage){
print(remoteMessage.appData)
//let title = remoteMessage.appData[("data"): {"title"}]
var title = "New Request"
for value in remoteMessage.appData{
if let value = value as? [AnyHashable:Any]{
print(value)
}
}
let message = "okay"
print(message)
self.showAlertAppDelegate(title: title ,message:message ,buttonTitle:"ok",window:self.window!)
print(title, message)
}
But I still have the warning so is there any actions should I do more ?

I found the problem, which is I forgot this line
Messaging.messaging().delegate = self
in this method:
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {}

Related

iOS 12 not received FCM notifications

Hi I'm using XCode version: 10.1 (10B61) and iPhone SE with iOS version: 12.0.1 (16A404), I installed properly all configuration as documentation explained, I uploaded the Auth .p8 certificate and the p.12 certificates of development and production, but when I try to send a push notification from Firebase console I don't receive any, am I missing something? or I did some wrong? any help, please?
//
// AppDelegate.swift
// SpriteKit Game Demo
//
// Created by Dennis Mostajo on 9/2/18.
// Copyright © 2018 Mostys Studios.. All rights reserved.
//
import UIKit
import Fabric
import Crashlytics
import Firebase
import UserNotifications
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate
{
var window: UIWindow?
var navigationVC: UINavigationController?
let gcmMessageIDKey = "gcm.message_id"
override init() {
// set Firebase configuration
FirebaseApp.configure()
}
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
debugPrint("didFinishLaunchingWithOptions")
Fabric.with([Crashlytics.self])
DataBaseHelper.DBUpdate() // Run migrations
// Enable Push Notifications
Messaging.messaging().delegate = self
Messaging.messaging().shouldEstablishDirectChannel = true
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)
}
application.registerForRemoteNotifications()
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.
debugPrint("applicationWillResignActive")
}
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.
debugPrint("applicationDidEnterBackground")
}
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.
debugPrint("applicationWillEnterForeground")
}
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.
debugPrint("applicationDidBecomeActive")
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
debugPrint("applicationWillTerminate")
}
// MARK: - FIREBASE
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any])
{
Messaging.messaging().appDidReceiveMessage(userInfo)
if let messageID = userInfo[gcmMessageIDKey]
{
debugPrint("Message ID: \(messageID)")
}
// Print full message.
debugPrint(userInfo)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void)
{
Messaging.messaging().appDidReceiveMessage(userInfo)
if let messageID = userInfo[gcmMessageIDKey]
{
debugPrint("Message ID: \(messageID)")
}
// Print full message.
debugPrint(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error)
{
debugPrint("Unable to register for remote notifications: \(error.localizedDescription)")
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
{
debugPrint("didRegisterForRemoteNotificationsWithDeviceToken: DATA")
let token = String(format: "%#", deviceToken as CVarArg)
debugPrint("*** deviceToken: \(token)")
let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
debugPrint("deviceTokenString: \(deviceTokenString)")
Messaging.messaging().apnsToken = deviceToken
// debugPrint("Firebase Token:",InstanceID.instanceID().token() as Any)
}
}
// [START ios_10_message_handling]
#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) {
//Handle the notification ON APP
Messaging.messaging().appDidReceiveMessage(notification.request.content.userInfo)
completionHandler([.sound,.alert,.badge])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void) {
//Handle the notification ON BACKGROUND
Messaging.messaging().appDidReceiveMessage(response.notification.request.content.userInfo)
completionHandler()
}
}
// [END ios_10_message_handling]
extension AppDelegate : MessagingDelegate {
// [START refresh_token]
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
print("Firebase registration token: \(fcmToken)")
InstanceID.instanceID().instanceID
{
(result, error) in
if let error = error
{
debugPrint("Error fetching remote instange ID: \(error)")
}
else if let result = result
{
debugPrint("Remote instance ID token: \(result.token)")
}
}
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.
}
// [END refresh_token]
// [START ios_10_data_message]
// Receive data messages on iOS 10+ directly from FCM (bypassing APNs) when the app is in the foreground.
// To enable direct data messages, you can set Messaging.messaging().shouldEstablishDirectChannel to true.
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
debugPrint("Received data message: \(remoteMessage.appData)")
}
// [END ios_10_data_message]
}
Podfile:
# Uncomment the next line to define a global platform for your project
platform :ios, '10.0'
def shared_pods
pod 'Fabric'
pod 'Crashlytics'
pod 'Alamofire', '~> 4.7'
pod 'RealmSwift'
pod 'SwiftyJSON'
pod 'PKHUD', '~> 5.0'
pod 'Siren'
pod 'Firebase/Core'
pod 'Firebase/Messaging'
pod 'Firebase/DynamicLinks'
pod 'Firebase/Crash'
end
target 'Sprite Kit Game' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
# Pods for Sprite Kit Game
shared_pods
end
target 'Sprite Kit GameTests' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
# Pods for testing
shared_pods
end
target 'Sprite Kit GameUITests' do
# Comment the next line if you're not using Swift and don't want to use dynamic frameworks
use_frameworks!
# Pods for testing
shared_pods
end
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
# This works around a unit test issue introduced in Xcode 10.
# We only apply it to the Debug configuration to avoid bloating the app size
if config.name == "Debug" && defined?(target.product_type) && target.product_type == "com.apple.product-type.framework"
config.build_settings['ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES'] = "YES"
end
end
end
end
no notifications are received neither by foreground nor background, any help, please?
The issue was resolved to update this part of the code handling the message/push notification from Firebase console
// [START ios_10_message_handling]
#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
if let messageID = userInfo[gcmMessageIDKey] {
debugPrint("Message ID: \(messageID)")
}
debugPrint(userInfo)
//Handle the notification ON APP
Messaging.messaging().appDidReceiveMessage(userInfo)
completionHandler([.sound,.alert,.badge])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
if let messageID = userInfo[gcmMessageIDKey] {
debugPrint("Message ID: \(messageID)")
}
//Handle the notification ON BACKGROUND
Messaging.messaging().appDidReceiveMessage(userInfo)
completionHandler()
}
}
// [END ios_10_message_handling]
the issue was tracked on GitHub
Make sure you updated iOS Deployment Target in the NotificationService settings

Push notification is not working when app is in background (minimized) - iOS

I'm newbie to Swift, I am creating chat application, I need to send notification when app is in foreground or minimized.
But I am not getting the notification when app is minimized (it works when USB is connected.
Enabled Remote notification
Background Fetches in Xcode setup
Enabled Push Notification
Production APns certificate
Notification code:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
let gcmMessageIDKey = "gcm.message_id"
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
Messaging.messaging().delegate = self
Messaging.messaging().shouldEstablishDirectChannel = true
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .sound, .badge]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .sound, .badge], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
NotificationCenter.default.addObserver(self, selector: #selector(tokenRefreshNotification(_:)), name: NSNotification.Name.InstanceIDTokenRefresh, object: nil)
return true
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
Messaging.messaging().appDidReceiveMessage(userInfo)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
Messaging.messaging().appDidReceiveMessage(userInfo)
let action = userInfo["action"] as! String
let notification = UILocalNotification()
notification.fireDate = NSDate() as Date
notification.alertTitle = "test"
notification.alertBody = "test"
notification.alertAction = "Ok"
UIApplication.shared.applicationIconBadgeNumber = 1
UIApplication.shared.scheduleLocalNotification(notification)
completionHandler(UIBackgroundFetchResult.newData)
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Unable to register for remote notifications: \(error.localizedDescription)")
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("APNs token retrieved: \(deviceToken)")
// With swizzling disabled you must set the APNs token here.
Messaging.messaging().apnsToken = deviceToken
}
}
#available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
completionHandler([.alert, .sound, .badge])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
print(userInfo)
completionHandler()
}
#objc func tokenRefreshNotification(_ notification: Notification) {
guard let token = InstanceID.instanceID().token() else {
print("No firebase token, aborting registering device")
return
}
print("No firebase token, aborting registering device")
}
}
extension AppDelegate : MessagingDelegate {
// [START refresh_token]
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
print("Firebase registration token: \(fcmToken)")
Messaging.messaging().subscribe(toTopic: "/topics/channel_18")
}
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
print("Received data message: \(remoteMessage.appData)")
}
}
FCM Payload:
{
"to" : "/topics/channel_18",
"data" : {
"action" : "NOTIFY",
"message" : "{"text":"test" }"
},
"content_available" : true
}
I have tried with Priority high and with Sound option but none works.
Please note that I am not using "notification" key as per client request. i am using only data-message in FCM payload
Please anyone help me to work notification when app is in background without USB connection.
If it works with non-Silent notification then all it means is:
Then payload is not correctly setup. Based on the answers provided to this question I'd just alter the placement of the content_available field into notification(and since you don't want a title body then just don't add title/body) or just into the payload itself until see it working.
I'd also make sure all the correct capabilities in Xcode are set (Enabled Remote notification, Background Fetches in Xcode setup, Enabled Push Notification). As mentioned previously uncheck and recheck all of them again.
And make sure Background App refresh is enabled for your app. This is NOT the same with your notifications. Obviously make sure your notifications are also enabled.:
But if you tried everything and it just doesn't work for 11.3 then it might be a bug. There is this other open question mentioned the same issue of yours. Run the app directly from tapping the app, ie not launching from Xcode and then use the console to see what it's logging related to the silent notification. If you're getting something like this:
default 13:11:47.178186 +0200 dasd DuetActivitySchedulerDaemon Removing a launch request for application <private> by activity <private> default com.apple.duetactivityscheduler
Then likely it's a bug similar to this iOS11 question. But you must open a new radar, because that radar was closed I believe because it was fixed!

How to implement Push notification in xcode 7.3

I want to implement older Firebase notification any link for older SDKs and old Pod version
I am using Xcode 7.3 and I want to implement firebase push notification but
due to latest pod I can't run project and comes error in FIRMessagingDelegate and FIRInstanceID I install both pod but method is not working.
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
let notificationTypes: UIUserNotificationType = [UIUserNotificationType.Alert, UIUserNotificationType.Badge, UIUserNotificationType.Sound]
let pushNotificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: nil)
application.registerUserNotificationSettings(pushNotificationSettings)
application.registerForRemoteNotifications()
return true
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
print("DEVICE TOKEN = \(deviceToken)")
}
func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
print(error)
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
print(userInfo)
}
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 throttle down OpenGL ES frame rates. 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 inactive 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(_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 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()
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("APNs token retrieved: \(deviceToken)")
// With swizzling disabled you must set the APNs token here.
// Messaging.messaging().apnsToken = deviceToken
}
Finding pod Version in change log and install pod
pod 'Firebase', '~> 3.10'
pod 'FirebaseMessaging', '~> 1.0’
and after install pod
letest pod dose't suppot userNotifications Framwork

Firebase Issues iOS 10.3 on Xcode 8.3 Swift 3 FCM notifications not working

I'm working on Xcode 8.3.2 for iOS 10.3.2 with Swift 3, my project use firebase cloud messaging, when my p12 certificates expired, I updated my certificates p12 to p8 as suggested Firebase's documentation, but the push notifications stopped coming, yesterday when I used the console firebase to test, it was working but today no, the logs print me this as normal:
2017-05-30 10:13:23.932066-0400 lol[5576:1530669] WARNING: Firebase Analytics App Delegate Proxy is disabled. To log deep link campaigns manually, call the methods in FIRAnalytics+AppDelegate.h.
2017-05-30 10:13:23.949512-0400 lol[5576:1530669] Firebase automatic screen reporting is enabled. Call +[FIRAnalytics setScreenName:setScreenClass:] to set the screen name or override the default screen class name. To disable automatic screen reporting, set the flag FirebaseAutomaticScreenReportingEnabled to NO in the Info.plist
2017-05-30 10:13:24.368364-0400 lol[5576:1530669] [Crashlytics] Version 3.8.2 (118)
2017-05-30 10:13:24.397942-0400 lol[5576:1530669] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles
2017-05-30 10:13:24.398433-0400 lol[5576:1530669] [MC] Reading from public effective user settings.
initializeFCM
Notification access accepted.
2017-05-30 10:13:24.679: <FIRInstanceID/WARNING> Failed to fetch APNS token Error Domain=com.firebase.iid Code=1001 "(null)"
2017-05-30 10:13:24.681: <FIRMessaging/INFO> FIRMessaging library version 1.2.0
2017-05-30 10:13:24.683213-0400 lol[5576:1530706] [Firebase/Crash][I-CRA000004] Successfully initialized
2017-05-30 10:13:24.683 lol[5576] <Notice> [Firebase/Crash][I-CRA000004] Successfully initialized
2017-05-30 10:13:24.685110-0400 lol[5576:1530706] <FIRAnalytics/INFO> Firebase Analytics v.3600000 started
2017-05-30 10:13:24.685 lol[5576:] <FIRAnalytics/INFO> Firebase Analytics v.3600000 started
2017-05-30 10:13:24.685438-0400 lol[5576:1530706] <FIRAnalytics/INFO> To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled
2017-05-30 10:13:24.685 lol[5576:] <FIRAnalytics/INFO> To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled
"GCM TOKEN = Optional(\"it's working: PLEASE HELP STACKOVERFLOW\")"
"didRegisterForRemoteNotificationsWithDeviceToken: DATA"
"*** deviceToken: <66666666 it's working: PLEASE HELP STACKOVERFLOW 99999999>"
2017-05-30 10:13:24.837: <FIRInstanceID/WARNING> APNS Environment in profile: development
"Firebase Token:" Optional("it's working: PLEASE HELP STACKOVERFLOW")
2017-05-30 10:13:24.932076-0400 lol[5576:1530727] <FIRAnalytics/INFO> Firebase Analytics enabled
2017-05-30 10:13:24.932 lol[5576:] <FIRAnalytics/INFO> Firebase Analytics enabled
"Connected to FCM."
the new strange log is:
2017-05-30 10:13:24.679: <FIRInstanceID/WARNING> Failed to fetch APNS token Error Domain=com.firebase.iid Code=1001 "(null)"
my code is:
//
// AppDelegate.swift
// lol
//
// Created by Dennis Mostajo on 06/06/16. ---> 666 the number of the beast! O_O!
// Copyright © 2016 Dennis Mostajo. All rights reserved.
//
import UIKit
import FirebaseAnalytics
import FirebaseInstanceID
import FirebaseMessaging
import UserNotifications
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
{
// Override point for customization after application launch.
self.initializeFCM(application)
let token = FIRInstanceID.instanceID().token()
debugPrint("GCM TOKEN = \(String(describing: token))")
return true
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error)
{
debugPrint("didFailToRegisterForRemoteNotificationsWithError: \(error)")
}
func applicationReceivedRemoteMessage(_ remoteMessage: FIRMessagingRemoteMessage)
{
debugPrint("remoteMessage:\(remoteMessage.appData)")
}
func initializeFCM(_ application: UIApplication)
{
print("initializeFCM")
//-------------------------------------------------------------------------//
if #available(iOS 10.0, *) // enable new way for notifications on iOS 10
{
let center = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options: [.badge, .alert , .sound]) { (accepted, error) in
if !accepted
{
print("Notification access denied.")
}
else
{
print("Notification access accepted.")
UIApplication.shared.registerForRemoteNotifications();
}
}
}
else
{
let type: UIUserNotificationType = [UIUserNotificationType.badge, UIUserNotificationType.alert, UIUserNotificationType.sound];
let setting = UIUserNotificationSettings(types: type, categories: nil);
UIApplication.shared.registerUserNotificationSettings(setting);
UIApplication.shared.registerForRemoteNotifications();
}
FIRApp.configure()
NotificationCenter.default.addObserver(self, selector: #selector(self.tokenRefreshNotificaiton),
name: NSNotification.Name.firInstanceIDTokenRefresh, object: nil)
}
func registrationhandler(_ registrationToken: String!, error: NSError!)
{
if (registrationToken != nil)
{
debugPrint("registrationToken = \(String(describing: registrationToken))")
}
else
{
debugPrint("Registration to GCM failed with error: \(error.localizedDescription)")
}
}
func tokenRefreshNotificaiton(_ notification: Foundation.Notification)
{
if let refreshedToken = FIRInstanceID.instanceID().token()
{
debugPrint("InstanceID token: \(refreshedToken)")
}
connectToFcm()
}
func connectToFcm()
{
// Won't connect since there is no token
guard FIRInstanceID.instanceID().token() != nil else
{
return;
}
// Disconnect previous FCM connection if it exists.
FIRMessaging.messaging().disconnect()
FIRMessaging.messaging().connect { (error) in
if (error != nil)
{
debugPrint("Unable to connect with FCM. \(String(describing: error))")
}
else
{
debugPrint("Connected to FCM.")
}
}
}
func application(_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings)
{
debugPrint("didRegister notificationSettings")
if (notificationSettings.types == .alert || notificationSettings.types == .badge || notificationSettings.types == .sound)
{
application.registerForRemoteNotifications()
}
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData)
{
debugPrint("didRegisterForRemoteNotificationsWithDeviceToken: NSDATA")
let token = String(format: "%#", deviceToken as CVarArg)
debugPrint("*** deviceToken: \(token)")
#if RELEASE_VERSION
FIRInstanceID.instanceID().setAPNSToken(deviceToken as Data, type:FIRInstanceIDAPNSTokenType.prod)
#else
FIRInstanceID.instanceID().setAPNSToken(deviceToken as Data, type:FIRInstanceIDAPNSTokenType.sandbox)
#endif
debugPrint("Firebase Token:",FIRInstanceID.instanceID().token() as Any)
}
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void)
{
//Handle the notification ON APP foreground
debugPrint("*** willPresent notification")
debugPrint("*** notification: \(notification)")
}
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void)
{
//Handle the notification ON BACKGROUND
debugPrint("*** didReceive response Notification ")
debugPrint("*** response: \(response)")
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
{
debugPrint("didRegisterForRemoteNotificationsWithDeviceToken: DATA")
let token = String(format: "%#", deviceToken as CVarArg)
debugPrint("*** deviceToken: \(token)")
#if RELEASE_VERSION
FIRInstanceID.instanceID().setAPNSToken(deviceToken as Data, type:FIRInstanceIDAPNSTokenType.prod)
#else
FIRInstanceID.instanceID().setAPNSToken(deviceToken as Data, type:FIRInstanceIDAPNSTokenType.sandbox)
#endif
debugPrint("Firebase Token:",FIRInstanceID.instanceID().token() as Any)
}
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
FIRMessaging.messaging().appDidReceiveMessage(userInfo)
if let messageID = userInfo["gcm.message_id"] {
debugPrint("Message ID: \(messageID)")
}
debugPrint("*** userInfo: \(userInfo)")
// Print full message.
completionHandler(.newData)
}
func application(_ application: UIApplication, didReceive notification: UILocalNotification)
{
if application.applicationState != UIApplicationState.active
{
if let gcmMessageType = GCMMessageType(rawValue: notificationType)
{
debugPrint("didReceiveLocalNotification")
debugPrint("notification:\(notification)")
}
}
//application.applicationIconBadgeNumber = 0
}
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.
connectToFcm()
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
I have made some mistake ?, or I need to configure something ?, something more that should increase for the difference between iOS 9 and iOS 10.3, or add to firebase settings, thanks a lot for any help
//------------------------------------------------------------------------------------------------------------------------------//
EDIT:
Hi again, well I have updated Firebase to the latest version 4.0.0, doing these updates in my code:
func initializeFCM(_ application: UIApplication)
{
print("initializeFCM")
//-------------------------------------------------------------------------//
if #available(iOS 10.0, *) // enable new way for notifications on iOS 10
{
let center = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options: [.badge, .alert , .sound]) { (accepted, error) in
if !accepted
{
print("Notification access denied.")
}
else
{
print("Notification access accepted.")
UIApplication.shared.registerForRemoteNotifications();
}
}
}
else
{
let type: UIUserNotificationType = [UIUserNotificationType.badge, UIUserNotificationType.alert, UIUserNotificationType.sound];
let setting = UIUserNotificationSettings(types: type, categories: nil);
UIApplication.shared.registerUserNotificationSettings(setting);
UIApplication.shared.registerForRemoteNotifications();
}
//-------------------------------------------------------------------------//
FirebaseApp.configure()
Messaging.messaging().shouldEstablishDirectChannel = true
NotificationCenter.default.addObserver(self, selector: #selector(self.tokenRefreshNotificaiton),
name: NSNotification.Name.InstanceIDTokenRefresh, object: nil)
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData)
{
debugPrint("didRegisterForRemoteNotificationsWithDeviceToken: NSDATA")
let token = String(format: "%#", deviceToken as CVarArg)
debugPrint("*** deviceToken: \(token)")
Messaging.messaging().apnsToken = deviceToken as Data
debugPrint("Firebase Token:",InstanceID.instanceID().token() as Any)
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
{
debugPrint("didRegisterForRemoteNotificationsWithDeviceToken: DATA")
let token = String(format: "%#", deviceToken as CVarArg)
debugPrint("*** deviceToken: \(token)")
Messaging.messaging().apnsToken = deviceToken
debugPrint("Firebase Token:",InstanceID.instanceID().token() as Any)
}
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage)
{
debugPrint("--->messaging:\(messaging)")
debugPrint("--->didReceive Remote Message:\(remoteMessage.appData)")
guard let data =
try? JSONSerialization.data(withJSONObject: remoteMessage.appData, options: .prettyPrinted),
let prettyPrinted = String(data: data, encoding: .utf8) else { return }
print("Received direct channel message:\n\(prettyPrinted)")
}
Several warnings logs disappeared but when I do the test in foreground and background way this logs print me:
2017-06-01 17:40:12.897916-0400 lol[8275:2217196] [Firebase/Messaging][I-FCM002019] FIRMessaging received data-message, but FIRMessagingDelegate's-messaging:didReceiveMessage: not implemented
2017-06-01 17:40:12.898 lol[8275] <Warning> [Firebase/Messaging][I-FCM002019] FIRMessaging received data-message, but FIRMessagingDelegate's-messaging:didReceiveMessage: not implemented
"###> 1.2 AppDelegate DidEnterBackground"
2017-06-01 17:40:29.943006-0400 lol[8275:2217037] Could not signal service com.apple.WebKit.WebContent: 113: Could not find specified service
2017-06-01 17:40:29.944689-0400 lol[8275:2217037] Could not signal service com.apple.WebKit.Networking: 113: Could not find specified service
2017-06-01 17:40:30.000428-0400 lol[8275:2217203] dnssd_clientstub read_all(27) DEFUNCT
"###> 1.3 AppDelegate DidBecomeActive"
2017-06-01 17:40:30.760941-0400 lol[8275:2217443] [Firebase/Messaging][I-FCM002019] FIRMessaging received data-message, but FIRMessagingDelegate's-messaging:didReceiveMessage: not implemented
2017-06-01 17:40:30.761 lol[8275] <Warning> [Firebase/Messaging][I-FCM002019] FIRMessaging received data-message, but FIRMessagingDelegate's-messaging:didReceiveMessage: not implemented
I tried this but it still shows those logs and it does not show any notifications:
is anything I'm missing?, Thanks for the answers!!
You need to add Push notification certificate to FCM Console in Cloud Messaging. Only then It'll be able to send notifications to your App. Also, make sure you've enabled Push notifications in Capabilities in your iOS App.
Update:
extension AppDelegate: MessagingDelegate {
// Registering for Firebase notifications
func configureFirebase(application: UIApplication) {
FirebaseApp.configure()
Messaging.messaging().delegate = self
// Register for remote notifications. This shows a permission dialog on first run, to
// show the dialog at a more appropriate time move this registration accordingly.
// [START register_for_notifications]
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)
}
application.registerForRemoteNotifications()
print("-----firebase token: \(String(describing: Messaging.messaging().fcmToken)) ----")
}
//MARK: FCM Token Refreshed
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
// FCM token updated, update it on Backend Server
}
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
print("remoteMessage: \(remoteMessage)")
}
//Called when a notification is delivered to a foreground app.
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .badge, .sound])
}
//Called to let your app know which action was selected by the user for a given notification.
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
print("User Info = \(response.notification.request.content.userInfo)")
completionHandler()
}
}
Call configureFirebase(application:) inside didFinishLaunchingWithOptions of your AppDelegate.

Get the push notification token - iOS 10, Swift 3

How to get the device token from new xCode 8, Swift 3 in iOS 10?
Here is the code to register notification:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
DispatchQueue.main.async {
let settings = UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)
UIApplication.shared.registerUserNotificationSettings(settings)
}
return true
}
func application(_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) {
if notificationSettings.types != UIUserNotificationType() {
application.registerForRemoteNotifications()
}
}
Here i get the token, but i get the following error
Cannot invoke initializer for type 'UnsafePointer<CChar>' with an argument list of type '(UnsafeRawPointer)':
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let chars = UnsafePointer<CChar>((deviceToken as NSData).bytes)
var token = ""
for i in 0..<deviceToken.count {
token += String(format: "%02.2hhx", arguments: [chars[i]])
}
print("Registration succeeded!")
print("Token: ", token)
}
Can anyone help me solve it?
This method may solve your problem in iOS 10 and greater:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
var token = ""
for i in 0..<deviceToken.count {
token = token + String(format: "%02.2hhx", arguments: [deviceToken[i]])
}
print(token)
}
var pushToken = String(format: "%#", deviceToken as CVarArg)
pushToken = pushToken.trimmingCharacters(in: CharacterSet(charactersIn: "<>"))
pushToken = pushToken.replacingOccurrences(of: " ", with: "")
Swift 3 example taken from raywenderlich.com.
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data){
let tokenParts = deviceToken.map { data -> String in
return String(format: "%02.2hhx", data)
}
let token = tokenParts.joined()
print(token)
}
One line:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let apnsDeviceToken = deviceToken.map {String(format: "%02.2hhx", $0)}.joined()
}
From this tutorial.
Or a modular/encapsulated/OOP way:
extension Data {
var string: String {
return map {String(format: "%02.2hhx", $0)}.joined()
}
}
Then you can do this:
let token = deviceToken.string
Faced the same problem, this is the only thing that helped me:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = String(format: "%#", deviceToken as CVarArg)
.trimmingCharacters(in: CharacterSet(charactersIn: "<>"))
.replacingOccurrences(of: " ", with: "")
}
The below snnipet is working with Eric Aya solution :
let token = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
Thanks for all help :)
Working Code for getting push notification token - iOS 11 or greater, Swift 4
Request user permission
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let notificationTypes: UIUserNotificationType = [UIUserNotificationType.alert,UIUserNotificationType.badge, UIUserNotificationType.sound]
let pushNotificationSettings = UIUserNotificationSettings(types: notificationTypes, categories: nil)
application.registerUserNotificationSettings(pushNotificationSettings)
application.registerForRemoteNotifications()
return true
}
Getting device token
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
print(token)
}
In case of error
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("i am not available in simulator \(error)")
}
It could work:
let chars = UnsafePointer<CChar>((deviceToken as NSData).bytes.assumingMemoryBound(to:CChar.self))
Thanks!
Code from Mixpanel library
let tokenChars = (deviceToken as NSData).bytes.assumingMemoryBound(to: CChar.self)
var tokenString = ""
for i in 0..<deviceToken.count {
tokenString += String(format: "%02.2hhx", arguments: [tokenChars[i]])
}
Since you may need this token in different methods (like firebase, web engage, branch, etc), you can use a custom class to initial an APNS from the data containing both data and string
public class APNS {
public init(deviceToken data: Data) {
self.data = data
self.string = data.map { data in String(format: "%02.2hhx", data) } .joined()
}
public let data: Data
public let string: String
}
then you can use it anywhere you need:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = APNS(deviceToken: deviceToken)
print(token.string)
}

Resources