Reputation: 613
I am working on an app in which I'm using FCM to send a push notification. I have followed the necessary steps to configure the push notification, i.e generating the certificate to adding entitlements and switch on remote notification in background mode, also uploaded the .p12 certificates with correct password in firebase console. The code I'm using for this is
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {
let gcmMessageIDKey = "gcm.message_id"
/// This method will be called whenever FCM receives a new, default FCM token for your
/// Firebase project's Sender ID.
/// You can send this token to your application server to send notifications to this device.
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String)
{
debugPrint("--->messaging:\(messaging)")
debugPrint("--->didRefreshRegistrationToken:\(fcmToken)")
}
@available(iOS 10.0, *)
public func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage)
{
debugPrint("--->messaging:\(messaging)")
debugPrint("--->didReceive Remote Message:\(remoteMessage.appData)")
let action_url = remoteMessage.appData["action_url"]! as! String
if let remoteDiscussion = action_url.slice(from: "https://xxxxxxxx.in/d/", to: "-"){
discussion = remoteDiscussion
window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "notificationDetailedItemNavigation") as! UINavigationController
}
}
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions:
[UIApplicationLaunchOptionsKey: Any]?) -> Bool {
debugPrint("###> 1 AppDelegate DidFinishLaunchingWithOptions")
self.initializeFCM(application)
if let token = InstanceID.instanceID().token(){
debugPrint("GCM TOKEN = \(String(describing: token))")
}
return true
}
func applicationDidEnterBackground(_ application: UIApplication) {
//FIRMessaging.messaging().disconnect()
debugPrint("###> 1.2 AppDelegate DidEnterBackground")
// self.doServiceTry()
}
func applicationDidBecomeActive(_ application: UIApplication) {
// connectToFcm()
application.applicationIconBadgeNumber = 0
debugPrint("###> 1.3 AppDelegate DidBecomeActive")
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error)
{
debugPrint("didFailToRegisterForRemoteNotificationsWithError: \(error)")
}
func application(received remoteMessage: MessagingRemoteMessage)
{
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.")
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
Messaging.messaging().subscribe(toTopic: "/topics/Men")
}
}
}
}
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().delegate = self
Messaging.messaging().shouldEstablishDirectChannel = true
NotificationCenter.default.addObserver(self, selector: #selector(self.tokenRefreshNotificaiton), name: NSNotification.Name.InstanceIDTokenRefresh, object: nil)
}
func tokenRefreshNotificaiton(_ notification: Foundation.Notification)
{
if let refreshedToken = InstanceID.instanceID().token()
{
debugPrint("InstanceID token: \(refreshedToken)")
}
// connectToFcm()
}
// 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, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if application.applicationState == .active {
if let aps = userInfo["data"] as? NSDictionary {
if let action_url = aps["action_url"] as? String {
// let alert = UIAlertController(title: "Notification", message: alertMessage, preferredStyle: UIAlertControllerStyle.alert)
// let action = UIAlertAction(title: "Ok", style: .default, handler: nil)
// alert.addAction(action)
// self.window?.rootViewController?.present(alert, animated: true, completion: nil)
print(action_url)
}
}
}
completionHandler(.newData)
}
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)
Messaging.messaging().subscribe(toTopic: "/topics/Men")
}
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
// InstanceID.instanceID().setAPNSToken(deviceToken as Data, type:InstanceIDAPNSTokenType.sandbox)
// #endif
Messaging.messaging().apnsToken = deviceToken
debugPrint("Firebase Token:",InstanceID.instanceID().token() as Any)
}
//-------------------------------------------------------------------------//
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 notification
// Print message ID.
Messaging.messaging().appDidReceiveMessage(userInfo)
if let messageID = userInfo["gcm.message_id"] {
debugPrint("Message ID: \(messageID)")
}
// Print full message.
print(userInfo)
}
func application(_ application: UIApplication, shouldSaveApplicationState coder: NSCoder) -> Bool {
return true
}
func application(_ application: UIApplication, shouldRestoreApplicationState coder: NSCoder) -> Bool {
return true
}
//------------------------------------------------------------------
}
// [START ios_10_message_handling]
@available(iOS 10, *)
extension AppDelegate {
// Receive displayed notifications for iOS 10 devices.
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
// With swizzling disabled you must let Messaging know about the message, for Analytics
// Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
// Print full message.
print(userInfo)
// Change this to your preferred presentation option
completionHandler([.alert, .badge, .sound])
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
// Print full message.
print(userInfo)
completionHandler()
}
}
On did receive method I've implemented printing the received message and instantiating a viewController which is working fine and whenever I'm sending a notification from postman if the app is running, it is opening up the targeted view controller, but notification is not coming.
I've checked many solutions in StackOverflow but can't figure out the problem. I'm stuck here for like 2 weeks, can anyone please help.
Upvotes: 5
Views: 5622
Reputation: 3008
For iOS10 and Above
Use UNUserNotificationCenterDelegate
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
completionHandler([.alert, .badge, .sound])
let userInfo:NSDictionary = notification.request.content.userInfo as NSDictionary
print(userInfo)
let dict:NSDictionary = userInfo["aps"] as! NSDictionary
let data:NSDictionary = dict["alert"] as! NSDictionary
RNNotificationView.show(withImage: UIImage(named: "image_Logo_Small"),
title: data["title"] as? String,
message: data["message"] as? String,
duration: 2,
onTap: {
print("Did tap notification")
})
}
This is code shows both native and RNNotifcation usage, i have kept in one code so you can use when it is needed(ios9/ios10). You will need to change the aspect that needs to be displayed according to your payload.
For below iOS10
The default Push Notification will not be shown when your App is in the foreground.
Push Notification gets displayed when your App is closed or is in Background. For Push to be shown when an app is in the background, you must select "Remote Notification" in "Background Mode".
Now to resolve your concern,
If you are looking for Third Party Library then I will recommend: https://github.com/souzainf3/RNNotificationView
Upvotes: 2