How to get push notification with FCM in background on iOS (Swift4)

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP



How to get push notification with FCM in background on iOS (Swift4)



How to get push notification in background? I have a problem in Swift4 iOS 11 with push notifications with FCM unable to retrieve notifications in the background only when the application is opened. Please help. thanks.



this is my coding:



AppDelegate.swift


@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate

var window: UIWindow?
static var DEVICE_ID = String()

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool

UIApplication.shared.statusBarStyle = .lightContent

FirebaseApp.configure()

if #available(iOS 10.0, *)
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self

UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound], completionHandler: (success, error) in
print(success)
)

Messaging.messaging().delegate = self

else
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)


application.registerForRemoteNotifications()

return true


func connectToFcm()
Messaging.messaging().shouldEstablishDirectChannel = true

if let token = InstanceID.instanceID().token()
AppDelegate.DEVICE_ID = token
print("*********")
print("Token Instance: (token)")
print("*********")



func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)

completionHandler([.alert, .sound])



func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String)
connectToFcm()


func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage)

guard let data: [String: Any] = remoteMessage.appData as? [String: Any] else
return


print(data)




func applicationDidBecomeActive(_ application: UIApplication)
UIApplication.shared.applicationIconBadgeNumber = 0
connectToFcm()


func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)


completionHandler(.newData)







Example: image send push notification with postman





Hey Just to confirm, you are not even getting the pop up for push notification and It is in case application is in killed state or just in background
– Nancy Madan
Aug 10 at 8:41





yes I did not get a notification when the application was killed and in the background. Is there my coding that is wrong or lacking. Please help
– Syahrir
Aug 10 at 9:13





I did't get what the problem is in your code. But I have posted my steps below. Please cross verify with your steps.
– Nancy Madan
Aug 10 at 9:26





I use the FCM method when the application is active and the notification appears successfully. When the application in my background uses the APN method and the notification does not appear and does not get notification data sent from the server. When I open the application again a notification appears.
– Syahrir
Aug 14 at 7:40




2 Answers
2



I am not able to find out the issue in your code but I am posting the steps how it should be done :-



Register for Push notifications


func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool



FirebaseApp.configure()
self.registerForPushNotifications(application)
return true

func registerForPushNotifications(_ application: UIApplication)
Messaging.messaging().delegate = self
if #available(iOS 10, *)


let center = UNUserNotificationCenter.current()
center.requestAuthorization(options:[.badge, .alert, .sound]) (granted, error) in
// Enable or disable features based on authorization.

center.delegate=self
application.registerForRemoteNotifications()

else
let settings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()




2.Then handle your didRegisterForRemoteNotificationsWithDeviceToken delegate :-


func application(_ application: UIApplication,

didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
Messaging.messaging().apnsToken = deviceToken




Handle your Firebase Messaging delegate :-



extension AppDelegate: MessagingDelegate
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String)


let token = fcmToken
// you can send your token to Server, from where you'll get the Push Notification







4.Then handle your UNUserNotificationCenterDelegate :-


func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
// this is called when application is Foreground and push arrives we show alert, sound, here.
completionHandler([.alert, .sound])


func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Swift.Void)
let pushDictionary = response.notification.request.content.userInfo
// handle your push here





I did what you said step by step but still the same I did not get a notification in the background
– Syahrir
Aug 10 at 9:52





Ok then go to your project. In target , select "Capabilities", then In "Background Modes", turn it on, and check "remote notifications" tab. And also enable "Push Notifications"
– Nancy Madan
Aug 10 at 10:01






yes I did it all
– Syahrir
Aug 10 at 10:19





Please verify( "alert": "true", "badge": "true", "sound": "true") is true on server end
– Nancy Madan
Aug 10 at 10:36





"priority": "high", "content_available": true, "alert": true, "badge": true, "sound": true, "notification": "title": "Notification Test", "body": "Body testing", "badge": "1" , "registration_ids": [ "tokenId" ] Is this what you mean?
– Syahrir
Aug 10 at 11:03



this source code in AppDelegate.swift:


import UIKit
import UserNotifications
import FirebaseCore
import FirebaseMessaging
import FirebaseInstanceID

struct DataNotif: Codable
var title: String?
var body: String?

private enum CodingKeys: String, CodingKey
case title
case body



@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate

var window: UIWindow?
let gcmMessageIDKey = "message_id"

static var DEVICE_ID = String()
var msg_body = ""
var msg_title = ""

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool

UIApplication.shared.statusBarStyle = .lightContent

FirebaseApp.configure()

Messaging.messaging().delegate = self

if #available(iOS 10.0, *)
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self

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


application.registerForRemoteNotifications()

return true


func connectToFcm()
Messaging.messaging().shouldEstablishDirectChannel = true


func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)

if let refreshedToken = InstanceID.instanceID().token()
AppDelegate.DEVICE_ID = refreshedToken
print("*********")
print("InstanceID token: (refreshedToken)")
print("*********")
else
print("Can't get token device")


connectToFcm()



func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error)
print("Failed to register for remote notifications with error: (error)")


func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)

print(userInfo)

guard let data: [String: Any] = userInfo as? [String: Any] else
return


let listData = data["notification"] as! String
let jsonData = listData.data(using: .utf8)
do
let decoder = JSONDecoder()
let dataJson = try decoder.decode(DataNotif.self, from: jsonData!)

msg_body = dataJson.body!
msg_title = dataJson.title!

createNotification(title: msg_title, body: msg_body)

catch
print("error")


completionHandler(.newData)


// messaging
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String)

if let token = InstanceID.instanceID().token()
AppDelegate.DEVICE_ID = token
print("*********")
print("Token Instance: (token)")
print("*********")


connectToFcm()


func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage)

print("Received data message: (remoteMessage.appData)")

guard let data: [String: Any] = remoteMessage.appData as? [String: Any] else
return


print(data)

let listData = data["notification"] as! String
let jsonData = listData.data(using: .utf8)
do
let decoder = JSONDecoder()
let dataJson = try decoder.decode(DataNotif.self, from: jsonData!)

msg_body = dataJson.body!
msg_title = dataJson.title!

createNotification(title: msg_title, body: msg_body)

catch
print("error")




func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)

completionHandler([.alert, .badge, .sound])


func applicationDidBecomeActive(_ application: UIApplication)
UIApplication.shared.applicationIconBadgeNumber = 0
connectToFcm()


func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)

if let vc = window?.rootViewController as? HomeController
vc.scheduleNotification()


completionHandler(.newData)



func applicationDidEnterBackground(_ application: UIApplication)
Messaging.messaging().shouldEstablishDirectChannel = false
print("Disconnect FCM")


func createNotification(title: String, body: String)
let content = UNMutableNotificationContent()
content.title = NSString.localizedUserNotificationString(forKey: title, arguments: nil)
content.body = NSString.localizedUserNotificationString(forKey: body, arguments: nil)
content.sound = UNNotificationSound.default()
content.badge = NSNumber(integerLiteral: UIApplication.shared.applicationIconBadgeNumber + 1)

let request = UNNotificationRequest.init(identifier: "pushNotif", content: content, trigger: nil)

let center = UNUserNotificationCenter.current()
center.add(request)








By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard