I am running into a very weird problem. After uninstalling and reinstalling my iOS 11 app (coded in swift), I have to launch the app multiple times (10 to 20) before my firebase messaging works again. I change nothing in the code (sometimes I just wait and hour or so) and for some reason it seems that Firebase Messaging Notifications only work after relaunching my app multiple times. It's very important for my app to be able to receive notifications right when it's first opened as my app is basically reliant on them. I just need to find a way to get notifications to work when I first launch the app after I install it. I've attached images of my code. (I have method_swizzling enabled)
If someone could please help me I would really appreciate it. I've seen youtube videos doing the same things I'm doing and they're able to get messages to work right away. I've tried a lot of what I've seen online and other questions that seem to be like this but none of their methods seem to work. Thank you so much to anyone who tries to help!
[edit]
This is the code for the application launch function:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
application.statusBarStyle = ColorScheme.isDark ? .lightContent : .default
FirebaseApp.configure()
// Messaging.messaging().delegate = self
// Messaging.messaging().shouldEstablishDirectChannel = true
// UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .alert, .sound]) { (granted, error) in }
// application.registerForRemoteNotifications()
setupMessaging(application: application)
}
This is the code for actually connecting and setting up my Firebase Messaging:
extension AppDelegate {
func setupMessaging(application: UIApplication) {
Messaging.messaging().delegate = self
Messaging.messaging().shouldEstablishDirectChannel = true
print("channel established", Messaging.messaging().isDirectChannelEstablished)
if #available(iOS 10.0, *) {
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()
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().setAPNSToken(deviceToken, type: .sandbox)
//TODO: Change for release
}
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
}
}
And this is the debug functions that are called when I receive the notification:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
print("I got a notification")
print(userInfo)
}
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
print("remote message received")
}
P.S. my AppDelegate extends MessagingDelegate and UNUserNotificationCenterDelegate
Please Check the below code
import Firebase
import FirebaseMessaging
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
Messaging.messaging().delegate = self
//REMOTE NOTIFICATION
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()
Messaging.messaging().delegate = self
let token = Messaging.messaging().fcmToken
print("FCM token: \(token ?? "")")
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self
} else {
// Fallback on earlier versions
}
return true
}
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken as Data
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
// Print full message.
print(userInfo)
}
// This method will be called when app received push notifications in foreground
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void)
{
completionHandler([UNNotificationPresentationOptions.alert,UNNotificationPresentationOptions.sound,UNNotificationPresentationOptions.badge])
}
// MARK:- Messaging Delegates
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
InstanceID.instanceID().instanceID { (result, error) in
if let error = error {
print("Error fetching remote instange ID: \(error)")
} else if let result = result {
print("Remote instance ID token: \(result.token)")
}
}
}
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
print("received remote notification")
}
}
I found the answer! The problem was that I was using the online console firebase provides to send my test messages. I guess it time to register devices. I switched over to firebase functions to send my notification and then subscribed to a test topic with my phone and that fixed everything. I get notifications on first app launch now and I'm happy
Related
I am sending push notification by using FCM and PushTry, While the app is in suspended mode (App is closed) notification is coming but while app in foreground mode (App is open) notification coming but not showing banner.
didReceiveRemoteNotification notification method is calling when app in foreground mode and print data but not showing banner.
Code:-
import UIKit
import FirebaseCore
import FirebaseMessaging
import IQKeyboardManagerSwift
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window : UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]?) -> Bool {
FirebaseApp.configure()
Messaging.messaging().delegate = self
registerForFirebaseNotification(application: application)
return true
}
func registerForFirebaseNotification(application: UIApplication) {
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()
}
}
extension AppDelegate: MessagingDelegate {
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
print("Firebase token: \(fcmToken ?? "")")
let dataDict: [String: String] = ["token": fcmToken ?? ""]
NotificationCenter.default.post( name: Notification.Name("FCMToken"),object: nil, userInfo: dataDict )
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken
}
//UNUserNotificationCenterDelegate
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
print("APNs received with: \(userInfo)")
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
let content = notification.request.content
print("\(content.userInfo)")
completionHandler([.banner, .list, .sound]) // Display notification Banner
}
}
Print:-
APNs received with: [AnyHashable("google.c.sender.id"): 0000000000,
AnyHashable("google.c.fid"): 000000000, AnyHashable("google.c.a.e"): 1,
AnyHashable("aps"): {
alert = {
body = 22eeee;
title = 11;
};
"content-available" = 1;
}, AnyHashable("gcm.message_id"): 00000000]
App Notification Setting Screen:-
ScreenShot
Question: Can someone please explain to me how to show banner when app in foreground mode, I've tried with above code but no results yet. If i'm doing wrong please correct me.
Can someone please explain to me show notification banner?
Any help would be greatly appreciated.
Thanks in advance.
I am trying to implement push notification via FCM (Firebase Cloud Messaging). Right now, I'm using Messaging.messaging().subscribe for background push notification.
But somehow one minute the push notification works and after a while it doesn't work completely. Then, when I reboot the device, push notification starts working again. What would be the problem??
This is the basic setup in AppDelegate
import UIKit
import UserNotifications
import Firebase
#UIApplicationMain
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()
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)
}
Messaging.messaging().delegate = self
// Messaging.messaging().unsubscribe(fromTopic: "dev_store_abcde-acbcd-adbcd-bcddd") { error in
// print("unsub")
// }
application.registerForRemoteNotifications()
return true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let deviceTokenString = deviceToken.hexString
print(deviceTokenString)
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)")
}
}
}
// 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 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)
Messaging.messaging().subscribe(toTopic: "dev_store_id") { error in
print("Subscribe to dev_store_id")
}
// TODO: If necessary send token to application server.
// Note: This callback is fired at each app startup and whenever a new token is generated.
}
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
print("Message Data", remoteMessage.appData)
}
}
#available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
print(userInfo["value"])
UserDefaults.standard.set(true, forKey: "isNotified")
UserDefaults.standard.synchronize()
completionHandler(.newData)
}
}
extension Data {
var hexString: String {
let hexString = map { String(format: "%02.2hhx", $0) }.joined()
return hexString
}
}
Turns out after turning on/off wifi seems to work for the development build. If notification is deployed to the distribution build, silent notification is working considerably well.
I am setting up push notifications, and everything is going well until I try to get the FCM token so I can send a test message to an actual device. Using the pods Firebase 5.8.0, FirebaseCore (5.1.3), FirebaseInstanceID (3.2.1), and FirebaseMessaging (3.1.2), I can get the APNS token fine but every time I try to get the FCM token, it comes out as nil or when I use InstanceID.instanceID().instanceID(handler:) it results in some timeout error code 1003 and a result of nil. didReceiveRegistrationToken does not get called either. I've tried a many 2017 solutions but they're either deprecated or don't work. MessageDelegate and UNUserNotificationCenterDelegate are set, push notifications, and keychain sharing are enabled in capabilities, method swizzling is off via p-list and Here is my didRegisterForRemoteNotificationsWithDeviceToken function where I correctly get the apns token. Any ideas? Thanks.
`public func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("Registration Successful: Device token \(deviceToken)")
Messaging.messaging().apnsToken = deviceToken
print("Messaging APNS Token:\(Messaging.messaging().apnsToken)")
print("Instance Id: \(InstanceID.instanceID().token())") //deprecated & returns nil
print("Messaging APNS Token:\(Messaging.messaging().apnsToken)")
print("Token:\(Messaging.messaging().fcmToken)") // return nil
InstanceID.instanceID().instanceID { (result, error) in
if let result = result {
print("Result:\(String(describing: result?.token))")
} else {
print("Error:\(error))")
} //returns after about 2 mins with an firebase iid error of 1003
}
Please check the below app delegate code.
import UIKit
import Firebase
import FirebaseMessaging
import UserNotifications
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
//REMOTE NOTIFICATION
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()
Messaging.messaging().delegate = self
let token = Messaging.messaging().fcmToken
print("FCM token: \(token ?? "")")
//Added Code to display notification when app is in Foreground
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self
} else {
// Fallback on earlier versions
}
return true
}
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken as Data
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
// Print full message.
print(userInfo)
}
// This method will be called when app received push notifications in foreground
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void)
{
completionHandler([UNNotificationPresentationOptions.alert,UNNotificationPresentationOptions.sound,UNNotificationPresentationOptions.badge])
}
// MARK:- Messaging Delegates
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
InstanceID.instanceID().instanceID { (result, error) in
if let error = error {
print("Error fetching remote instange ID: \(error)")
} else if let result = result {
print("Remote instance ID token: \(result.token)")
}
}
}
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
print("received remote notification")
}
}
I set this code in my AppDelegate:
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, FIRMessagingDelegate {
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
if #available(iOS 10.0, *) {
let authOptions: UNAuthorizationOptions = [.Alert, .Badge, .Sound]
UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions(authOptions, completionHandler: { (granted: Bool, error: NSError?) in
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.currentNotificationCenter().delegate = self
// For iOS 10 data message (sent via FCM)
FIRMessaging.messaging().remoteMessageDelegate = self
})
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [.Alert, .Sound, .Badge], categories: nil))
}
Also this parts:
internal func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
print(userInfo)
// 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
// Print message ID.
print("Message ID: \(userInfo["gcm.message_id"]!)")
// Print full message.
print(userInfo)
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject],
fetchCompletionHandler completionHandler: (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
// Print message ID.
print("Message ID: \(userInfo["gcm.message_id"]!)")
// Print full message.
print(userInfo)
}
#available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
//Handle the notification
}
#available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
//Handle the notification
}
I also uploaded development APNs into the Apple Developers. In the Firebase console it writes that notification was successfully sent, but I do not get any push notification. Can anyone please help me to detect where my mistake is?
I have worked on it for 3 days. Searched a lot, but nothing.
Add FIRApp.configure() to the didFinishLaunchingWithOptions:
Add FIRMessaging.messaging().connect { (error) in
if error != nil {
print("Unable to connect with FCM. \(error)")
} else {
print("Connected to FCM.")
} to the end of didFinishLaunchingWithOptions:
Implement the FIRMessageDelegate function
func applicationReceivedRemoteMessage(_ remoteMessage: FIRMessagingRemoteMessage) {
print(remoteMessage.appData)
}
Add FIRMessaging.messaging().appDidReceiveMessage(userInfo) to func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void)
The finishing code should look like this:
import UIKit
import Firebase
import UserNotifications
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, FIRMessagingDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FIRApp.configure()
if #available(iOS 10.0, *) {
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
// For iOS 10 data message (sent via FCM)
FIRMessaging.messaging().remoteMessageDelegate = self
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
FIRMessaging.messaging().connect { (error) in
if error != nil {
print("Unable to connect with FCM. \(error)")
} else {
print("Connected to FCM.")
}
}
application.registerForRemoteNotifications()
return true
}
func applicationReceivedRemoteMessage(_ remoteMessage: FIRMessagingRemoteMessage) {
print("applicationReceivedRemoteMessage ")
print(remoteMessage.appData)
}
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
// Print message ID.
print("Message ID: \(userInfo["gcm.message_id"]!)")
// 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
// Print message ID.
print("Message ID: \(userInfo["gcm.message_id"]!)")
// Print full message.
print(userInfo)
FIRMessaging.messaging().appDidReceiveMessage(userInfo)
}
For anyone still looking, check the last answer here: ios10, Swift 3 and Firebase Push Notifications (FCM)
Check your push notification entitlement and switch it on. Target > Capabilities > Push notifications.
I do like below in Swift 2. But It's not working in Swift 3. How Can I provide this? If someone explain this It would be great.
didFinishLaunchingWithOptions
let notificationSettings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
application.registerForRemoteNotifications()
and
func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
if notificationSettings.types != .None {
application.registerForRemoteNotifications()
}
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
print("Meesage ID \(userInfo["gcm_message_id"]!)")
print(userInfo)
}
I can do simple local notification but, I couldn't remote push notification from Firebase.
I tried
UNUserNotificationCenter.currentNotificationCenter().delegate = self
UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions([.Alert, .Badge, .Sound]) { (success, error:NSError?) in
if success {
print("Notification access true!")
application.registerForRemoteNotifications()
}
else {
print(error?.localizedDescription)
}
}
and
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
print("Meesage ID \(userInfo["gcm_message_id"]!)")
print(userInfo)
}
still doesn't work.
The AppDelegate method names have changed a little and UserNotifications framework has been introduced. You must use this framework for notifications in iOS 10 and above as the other methods are being deprecated.
import UserNotifications
...
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
...
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
// Enable or disable features based on authorization.
}
application.registerForRemoteNotifications()
return true
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> ()) {
print("Message ID \(userInfo["gcm.message_id"]!)")
print(userInfo)
}
...
}
Registering for Push Notifications in Xcode 8/Swift 3.0?
It is very important to remember that there may be different devices that run different versions of the iOS, and they may have different notification capabilities. I understand that the previous answer does point in the right direction.
We need to import FirebaseInstanceID, if we are to receive instance, or event based notifications. Such notifications are like the ones that pop-up when someone retweets our post, or likes a post, or a message notification.
However, if someone is looking for the complete code that goes into the didFinishLaunchingWithOptions function in AppDelegate, here it is:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
FIRApp.configure()
if #available(iOS 10.0, *) {
let authOptions : UNAuthorizationOptions = [.Alert, .Badge, .Sound]
UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions(
authOptions, completionHandler: {_,_ in })
} else {
// Fallback on earlier versions
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
}
application.registerForRemoteNotifications()
// Add observer for InstanceID token refresh callback.
NSNotificationCenter.defaultCenter().addObserver(self,
selector: #selector(self.tokenRefreshNotification),
name: kFIRInstanceIDTokenRefreshNotification,
object: nil)
return true
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject],
fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
// This is required if you are receiving a notification message while your app is in the background, which is the most common case!!
print("Message ID: \(userInfo["gcm.message_id"]!)")
print("%#", userInfo)
}
func tokenRefreshNotification(notification: NSNotification) {
if let refreshedToken = FIRInstanceID.instanceID().token() {
print("InstanceID token: \(refreshedToken)")
}
connectToFcm()
}
func connectToFcm() {
FIRMessaging.messaging().connectWithCompletion { (error) in
if (error != nil) {
print("Unable to connect with FCM. \(error)")
} else {
print("Connected to FCM.")
}
}
}
func applicationDidBecomeActive(application: UIApplication) {
connectToFcm()
}
func applicationDidEnterBackground(application: UIApplication) {
FIRMessaging.messaging().disconnect()
print("Disconnected from FCM.")
}
This is what works for me Xcode 8, Swift 3.
Inside didFinishLaunchingwithOptions func in AppDelegate.swift
if #available(iOS 10.0, *) {
let authOptions : UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {granted, error in
print(granted)
})
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
// For iOS 10 data message (sent via FCM)
FIRMessaging.messaging().remoteMessageDelegate = self
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
FIRApp.configure()
// [START set_messaging_delegate]
FIRMessaging.messaging().remoteMessageDelegate = self
// [END set_messaging_delegate]
And the Delegates required to receive notifications from firebase:
#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
// Print message ID.
print("Message ID: \(userInfo["gcm.message_id"]!)")
// Print full message.
print("%#", userInfo)
let aps = userInfo["aps"] as! [String: Any]
let notificationMessage = aps["alert"] as! String // processed content from notificaton
}
}
extension AppDelegate : FIRMessagingDelegate {
// Receive data message on iOS 10 devices.
func applicationReceivedRemoteMessage(_ remoteMessage: FIRMessagingRemoteMessage) {
print("%#", remoteMessage.appData)
}
}