I've followed Apple's suggestions to implement push notifications with Firebase, but I can't get notifications. I have created the APNS key in firebase and I have activated the notifications in the app. In Siginig & Capabilities I have added "Push Notification" "Background Modules" activating Remote notifiactions. This is the code in AppDelegate:
import UIKit import FirebaseCore import FirebaseMessaging
#UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool{
//Firebase
FirebaseApp.configure()
// Push Notifications
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert,
.badge, .sound]
UNUserNotificationCenter.current()
.requestAuthorization(
options: authOptions,
completionHandler: {_, _ in})
application.registerForRemoteNotifications()
Messaging.messaging().subscribe(toTopic:"topic_general")
return true
}
}
extension AppDelegate: UNUserNotificationCenterDelegate{
// Push Notifications Mostrar aunque el movil este activo / Segundo Plano
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandle: #escaping
(UNNotificationPresentationOptions) -> Void){
completionHandle([.alert, .badge, .sound])
}
}
Problems Notifications Firebase IOS
I just looked through what you did and a working version of Firebase Notifications I have running. I would try to share where there are differences
import UIKit
import Firebase
import FirebaseMessaging
import FirebaseCore
Then
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
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) { (status, pushError) in
if !status {
print(pushError?.localizedDescription as Any)
}
}
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
Messaging.messaging().delegate = self
return true
}
after which
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
let pushedInfo = notification.request.content.userInfo
print(pushedInfo, "JSON Content of the Push Notification")
}
My ideas as to why you might not be getting the notifications:
Push notifications can only be tested on a physical device. Doesn't work on simulator
It is possible that push notifications is not authorised on the device.
Kindly check these ideas and the code differences. It is highly possible that the issue is somewhere there.
PS: I don't remember why I checked for #available(iOS 10.0, *) the code is a bit old.
Related
I am integrating Firebase Push notification in my Flutter project. Push notifications are working fine in Android but I am getting following error when trying to run IOS app:-
[FirebaseMessaging][I-FCM002023] The object <Runner.AppDelegate: 0x2837f4b10> does not respond to -messaging:didReceiveRegistrationToken:. Please implement -messaging:didReceiveRegistrationToken: to be provided with an FCM token.
Following is my AppDelegate Code:-
`
import UIKit
import Flutter
import UserNotifications
import Firebase
#UIApplicationMain
#objc class AppDelegate: FlutterAppDelegate, MessagingDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
FirebaseApp.configure()
Messaging.messaging().delegate = self
GeneratedPluginRegistrant.register(with: self)
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()
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
`
Trying to integrate Firebase Notification in FLutter App and expecting Push notification in IOS.
Basically, you need to implement didReceiveRegistrationToken so that the app will generate FCM token. You can check out this similar post.
I am getting FCM messages pushed to my iOS device fine when in the background but not in the foreground. I have found a number of articles where others had the same issue and solved it by adding the willPresentNotification function. However this isn't solving the issue for me. My FCM code is as follows:
class FCMManager: NSObject, MessagingDelegate, UNUserNotificationCenterDelegate {
static let shared = FCMManager()
let database = Database.database().reference()
public func registerForPushNotifications() {
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .sound, .announcement, .badge, .carPlay, .providesAppNotificationSettings]
UNUserNotificationCenter.current()
.requestAuthorization( options: authOptions,
completionHandler: { granted, _ in
guard granted else {
print("Apple push notifications are not registered")
return
}
print("Apple push notifications are registered")
})
Messaging.messaging().delegate = self
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
updatePushTokenIfNeeded()
}
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
updatePushTokenIfNeeded()
}
}
My notification payloads are set up as:
["to" : "fcm_token",
"notification" : ["title" : "Message Title",
"body" : "Message Body",
"sound" : "default",
"badge" : 1]
]
Then my app delegate is as follows:
class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?
let notificationCenter = UNUserNotificationCenter.current()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
let fcmManager = FCMManager()
fcmManager.registerForPushNotifications()
return true
}
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
if #available(iOS 14, *) {
completionHandler([.banner])
} else {
completionHandler([.alert])
}
}
}
I wanted to set up Firebase Cloud Messaging(FCM) for my iOS app. I followed the firebase documentation but I can't seem to get it to work. This is my app delegate file:
import UIKit
import Firebase
import FirebaseAnalytics
import FirebaseMessaging
#main
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {
let gcmMessageIDKey = "gcmMessageIDKey"
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)
}
application.registerForRemoteNotifications()
Messaging.messaging().delegate = self
return true
}
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
print("Firebase registration token: \(String(describing: 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.
}
// 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 full message.
print(userInfo)
// Change this to your preferred presentation option
completionHandler([[.banner, .sound]])
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
// ...
// With swizzling disabled you must let Messaging know about the message, for Analytics
// Messaging.messaging().appDidReceiveMessage(userInfo)
// Print full message.
print(userInfo)
completionHandler()
}
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)
}
// 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.
}
}
I also set up the app capabilities:
capability setting
I also check many times that I have my APNs auth key right.
But when I tried to send a test notification from the firebase notification composer, nothing popped up on my phone. The function didReceiveRegistrationToken is working and provides a token, but when I used the token to 'send test message', nothing happened.
I tried to make an empty Xcode project side-by-side with the documentation to see if the issue is with my existing app, but it still didn't work.
Is there anything else that I'm missing here?
After updating my application to Swift 3 (what an experience that was! ) - I knew I had to rework the Notification code due to the changes in iOS10.
Using this helpful resource - I was able to recode and I am getting a valid connection
https://github.com/ashishkakkad8/Notifications10Swift/blob/master/Notifications10Swift/AppDelegate.swift
I also amended the Capabilties for the project, adding 1) Notifications, and 2) Background Modes / Remote Notifications.
However, when I send a test message thru the Azure 'test-send' feature, I don't receive it.
Here's the relevant code from my AppDelegate:
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Register for remote notifications
if #available(iOS 10.0, *) {
let center = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in
if error == nil{
UIApplication.shared.registerForRemoteNotifications()
}
}
}
else {
UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.sound, .alert, .badge], categories: nil))
UIApplication.shared.registerForRemoteNotifications()
}
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
{
let hub: SBNotificationHub = SBNotificationHub.init(connectionString: APISettings.Instance.notificationHubEndpoint, notificationHubPath: APISettings.Instance.notificationHubName)
hub.registerNative(withDeviceToken: deviceToken, tags: nil) { (error) -> Void in
if (error != nil){
print("Error registering for notifications: %#", error)
} else {
print("Registration ok")
}
}
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error)
{
print("Error = ",error.localizedDescription)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
print(userInfo)
}
// MARK: UNUserNotificationCenter Delegate // >= iOS 10
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
print("User Info = ",notification.request.content.userInfo)
completionHandler([.alert, .badge, .sound])
}
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
print("User Info = ",response.notification.request.content.userInfo)
completionHandler()
}
Any help would be greatly appreciated.
Try to call this function on didFinishLaunchingWithOptions and clean >Run your app
func registerNotification()
{
UIApplication.sharedApplication()
let application = UIApplication.sharedApplication()
if application.respondsToSelector(#selector(UIApplication.registerUserNotificationSettings(_:)))
{
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
}
}
func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
if notificationSettings.types != .None {
application.registerForRemoteNotifications()
}
}
Yesterday I updated 2 of my apps to swift 3.
func application(_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) {
UIApplication.shared.registerForRemoteNotifications()
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print(error.localizedDescription)
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
// Save Installation if registered successfully
}
//MARK: Recieved Notification
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
print("received a notification")
}
so background push notification works fine on both apps, but in one of my app its not receiving any pushes in foreground that is, didReceiveRemoteNotification is never getting called
Things I have checked, Push Notifications enabled in Capabilities
Using this code to register for push notifications on both apps
UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .alert, .sound], categories: nil))
Not only that, I have tried UNUserNotificationCenterDelegate for iOS 10 but still none of its delegate functions get called.
This only doesn't work on iOS 10 phones, iOS 8 and 9 works like charm.
So I'm not really sure why its never calling didReceiveRemoteNotification in only one of my 2 swift 3 apps on ios 10 when the app is open
This is my iOS 10 code I tried
//Added in didFinishLaunchingWithOptions
if #available(iOS 10.0, *) {
let center = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in
if error == nil{
UIApplication.shared.registerForRemoteNotifications()
}
}
}
//Delegates
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
print("push2")
}
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (UNNotificationPresentationOptions) -> Void) {
print("push1")
}
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
self.initializeNotificationServices()
}
func initializeNotificationServices() -> Void {
if #available(iOS 10.0, *) {
UNUserNotificationCenter.currentNotificationCenter().delegate = self
UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions([.Badge, .Sound, .Alert]) { (granted, error) in
if granted {
//self.registerCategory()
//self.scheduleNotification("test", interval: 3)
//self.scheduleNotification("test2", interval: 5)
let types : UIUserNotificationType = [.Badge, .Sound, .Alert]
let mySettings : UIUserNotificationSettings = UIUserNotificationSettings.init(forTypes: types, categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(mySettings)
UIApplication.sharedApplication().registerForRemoteNotifications()
}
}
}
else {
// Fallback on earlier versions
let settings = UIUserNotificationSettings(forTypes: [.Sound, .Alert, .Badge], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(settings)
// This is an asynchronous method to retrieve a Device Token
// Callbacks are in AppDelegate.swift
// Success = didRegisterForRemoteNotificationsWithDeviceToken
// Fail = didFailToRegisterForRemoteNotificationsWithError
UIApplication.sharedApplication().registerForRemoteNotifications()
}
}
#available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
print("willPresent")
completionHandler([.Badge, .Alert, .Sound])
}
#available(iOS 10.0, *)
func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
self.didReceiveBookingAppRemoteNotification(response.notification.request.content.userInfo)
print("didReceive == >> \(response.notification.request.content.userInfo)")
completionHandler()
}
//for Lower to ios 10 version
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
self.getNotifInfo(userInfo)
}
Make sure you have to enable push notification from project's
Target => Capabilities and you have to add it's framework UserNotifications.framework