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.
Related
I've linked my Swift Storyboard project with Firebase push notifications.
The notifications are currently arriving, but the problem is that the notifications are coming without sound or badge to display.
If I check the notification.request.content.sound or notification.request.content.badge... is displaying nil...
Anyone has face this? Do I missing something in the code to recieve the notification with the sound and badge?
class AppDelegate: UIResponder, UIApplicationDelegate {
var fcmTokenPreviafy: String = ""
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: { _, _ in }
)
application.registerForRemoteNotifications()
Messaging.messaging().delegate = self
return true
}
}
And here are the extensions:
extension AppDelegate: UNUserNotificationCenterDelegate{
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification) async -> UNNotificationPresentationOptions {
let userInfo = notification.request.content.userInfo
print(userInfo)
return [[ .alert, .badge, .sound ]]
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse) async {
let userInfo = response.notification.request.content.userInfo
print(userInfo)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) async -> UIBackgroundFetchResult {
print(userInfo)
return UIBackgroundFetchResult.newData
}
}
extension AppDelegate: MessagingDelegate{
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
)
fcmTokenPreviafy = fcmToken!
// TODO: If necessary send token to application server.
// Note: This callback is fired at each app startup and whenever a new token is generated.
}
}
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
I am not able to receive the notification from firebase. I have updated all pods and also uploaded the APNs Certificates for production. In Xcode i am managing the provisioning profile automatically and also enabled push notification, Remote notification(inside Background modes) in capabilities. Notification is enabled in setting section of device.
Here is my code in App delegate.
import UserNotifications
import Firebase
import FirebaseInstanceID
import FirebaseMessaging
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
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 })
// For iOS 10 data message (sent via FCM
Messaging.messaging().delegate = self
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
FirebaseApp.configure()
}
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: \(messageID)")
}
completionHandler(UIBackgroundFetchResult.newData)
}
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken
}
func applicationDidBecomeActive(_ application: UIApplication) {
Messaging.messaging().connect { error in
}
}
#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
//Here i do my navigation according to notification type
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
}
extension AppDelegate : MessagingDelegate {
//MARK: FCM Token Refreshed
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
let token = Messaging.messaging().fcmToken
let def = UserDefaults.standard
def.setValue(token, forKey: KDeviceToken)
print(def.object(forKey: KDeviceToken) ?? String())
}
// Receive data message on iOS 10 devices while app is in the foreground.
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
NSLog("remoteMessage: \(remoteMessage.appData)")
}
}
What ever I do the notification is not received.
Sending to Android is going fine, sending to iOS is a failure
I am sending from Firebase Console
I am not receiving foreground or background notification
here is the AppDelegate.swift
import UIKit
import Firebase
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.
if #available(iOS 10.0, *) {
UIView.appearance().semanticContentAttribute = .forceLeftToRight
}
FirebaseApp.configure()
// [START set_messaging_delegate]
Messaging.messaging().delegate = self as? MessagingDelegate
// [END set_messaging_delegate]
//create the notificationCenter
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 })
// 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()
return true
}
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("Registration succeeded! Token: ", token)
let topicName = "/topics/ChaclateOnMobile"
Messaging.messaging().subscribe(toTopic: topicName)
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Registration failed! \(error)")
}
// Firebase notification received
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: #escaping (_ options: UNNotificationPresentationOptions) -> Void) {
// custom code to handle push while app is in the foreground
print("Handle push from foreground\(notification.request.content.userInfo)")
let dict = notification.request.content.userInfo["aps"] as! NSDictionary
let d : [String : Any] = dict["alert"] as! [String : Any]
let body : String = d["body"] as! String
let title : String = d["title"] as! String
print("Title:\(title) + body:\(body)")
self.showAlertAppDelegate(title: title,message:body,buttonTitle:"ok",window:self.window!)
}
#available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
// if you set a member variable in didReceiveRemoteNotification, you will know if this is from closed or background
print("Handle push from background or closed\(response.notification.request.content.userInfo)")
}
func showAlertAppDelegate(title: String,message : String,buttonTitle: String,window: UIWindow){
let alert = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: buttonTitle, style: UIAlertActionStyle.default, handler: nil))
window.rootViewController?.present(alert, animated: false, completion: nil)
}
// Firebase ended here
}
Check if you are using the correct token for sending notifications.
Have you registered your app to receive Push Notifications?
Check if you have implemented proper methods in AppDelegate.
When the app is not running, the notification is received in didFinishLaunchingWithOptions.
Add this to didFinishLaunchingWithOptions in your code:
if let notification = launchOptions?[.remoteNotification] as? [String: AnyObject]
{
//Your code
}
When your app is in background/foreground, the notification is received in didReceiveRemoteNotification
func application(
_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void)
{
//Your code
}
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.