Notifications iOS 10 working building with Xcode but no with phone - ios

I'm using Firebase to handle notifications and once I have the notification I create a local notification (ios 9) or notification request (ios 10). All works well when I Build with Xcode and then Run, app receives notifications and it's shown.
But the problem is when I stop running the app through Xcode and I open, the notifications seems that never arrives in ios 10 version (but in ios 9 notifications are received as the first case without any problem).
Push notifications in Capabilities enabled, background modes too.
UserNotifications framework added
In didFinishLaunchingWithOptions I initialized all well:
/* NOTFICATIONS */
if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.currentNotificationCenter().delegate = self
let authOptions: UNAuthorizationOptions = [.Alert, .Badge, .Sound]
UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions(authOptions, completionHandler: { (_, _) in })
// 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()
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.tokenRefreshNotification(_:)), name: kFIRInstanceIDTokenRefreshNotification, object: nil)
I have UserNotification protocols implemented.
And I receive notifications here (in ios9 and ios10 i think, This could be where I'm wrong so maybe the notifications in ios10 are not handled directly here. But in this case how it's possible that I receive the notifications when app is running through xcode):
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
if #available(iOS 10.0, *) {
UNUserNotificationCenter.currentNotificationCenter().delegate = self
} else {
// Fallback on earlier versions
}
// Print message ID.
if let messageID = userInfo["gcmMessageIDKey"] {
print("Message ID: \(messageID)")
}
let notificationJSON = JSON(userInfo)
self.presentNotification(withNotificationJSON: notificationJSON)
FIRMessaging.messaging().appDidReceiveMessage(userInfo)
completionHandler(.NewData)
}
By the other hand I have my file .entitlements but with development (maybe need a release ones? Or it change by herself when compile?)
Thank you so much i'm a bit frustrated, any further information you need just let me know.
EDIT1:
Maybe the problem could be in the parameters?
let notificationsParameters:[String:AnyObject] = [
"to": "iphoneID",
"content-available":true,
"priority":"high",
"notification" : [
"sound" : " "
],
"data" : [
"Nick" : "Mario",
"Room" : "PortugalVSDenmark"
]
]

Related

Firebase Cloud messaging silent push notification to iOS not working while the prompting ones do

using Firebase Cloud messaging to send notification to iOS, the prompting ones work, however, the silent one never trigger any codes.
tested both on real device and simulator, iOS version is the latest, my codes with the UNUserNotificationCenterDelegate get triggered as expected when prompting push is received.
however, I put codes in application.didReceiveRemoteNotification and the codes never get triggered..., the func ffl is a thin wrapper of OSLog. the UserOb singleton is a simple object to write to UserDefaults.Standard so I can check the result offline. see below....
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
ffl("didReceiveRemoteNotification")
UserdOb.shared.apDelegateReceived()
AVUtility.shared.avAvPlayCaf(audioCaf: .alertSimple)
ffl(userInfo.description)
completionHandler(UIBackgroundFetchResult.newData)
}
below is code for delegate registration, again, prompting ones works. silent ones remain ... too silent (nothing happened)
fileprivate func registrateMe(application:UIApplication){
Messaging.messaging().delegate = self
if #available(iOS 10.0, *) {
let authOptions:UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(options: authOptions, completionHandler: {granted, error in
if granted{
UNUserNotificationCenter.current().delegate = self
}
})
}else{
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
UIApplication.shared.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
}
I have tried a lot of payloads of FCM (by postMan). here are some of them:nether works..., see below
{
"to": "[token]",
"data":{
"key1":"value1"
"key2":"value2"
},
"collapse_key":"update request",
"content_available":true,
"priority":"normal",
}
{"to" : "[token]",
"content_available": true,
"priority": "high",
"data" : {
"key1" : "abc",
"key2" : 123
}
"content_available": true,
"apns-priority": 5,
"data": {
"some-key": "some-value"
}
{
"to": "[token]",
"content_available":true,
"content-available":"1",
"aaa":"aaaa"
}
** the Apple APN service certificate is input into the Firebase App configuration. see screenshots
and I have the FCM server key in the authorization and it works find by header: Authorization:key=[], I don't think the prompting ones will work if these are not configured correctly.
the app has been tested both in active and background mode, either way the prompt ones work and the silent ones don't.

Update deprecated Firebase functions in Swift

I have this code to push app notifications.
It works well but I get this warning:
'MessagingRemoteMessage' is deprecated: FCM direct channel is deprecated, please use APNs for downstream message handling.
and this one 'appData' is deprecated
I made a research on Google but didn't find anything to fix this.
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
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()
return true
}
// The callback to handle data message received via FCM for devices running iOS 10 or above.
func applicationReceivedRemoteMessage(_ remoteMessage: MessagingRemoteMessage) {
print(remoteMessage.appData)
}
The question is whether you are simply sending display/alert notifications and background notifications? Or are you using direct channel to send some hidden data message for real time updates?
MessagingRemoteMessage is data message object sent and handled through direct channel. If you only want to push notifications, and you also don't seem to enable direct channel in your code above. You can use Apple's API UNUserNotificationCenterDelegate to handle alert message or AppDelegate application:didReceiveRemoteNotification:fetchCompletionHandler: to handle background notifications.

Sending a push notification to iOS through a CLI function

I am attempting to use a CLI function to send a push notification to both android and iOS devices. When I use the iOS version, no notification is received when sent from my function. However, when I send them from the Firebase console, it will receive the notification but only while the application is open. I am thinking I am missing either one or more crucial steps in setup or my function does not have all the needed data in the payload.
My function is sending as follows:
return Promise.all([token]).then(result=>{
const payload = {
notification: {
title : likename + " liked your post!",
"priority" : "high"
}
};
console.log(token);
return admin.messaging().sendToDevice(token,payload);
});
I have my iOS application set up with a certificate and have implemented my APP delegate as follows:
import UIKit
import Flutter
#UIApplicationMain
#objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: 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 })
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
Any help is greatly appreciated and please let me know if you need additional information.
After hours of reflection, I realized I had only implemented code to respond to the onLaunch or onResume versions. I had to implement those methods to my code and now have success.

How to block some firebase push notifications?

I have some parameters. Server send push notifications every devices but if parameters are on it can see notification with devices.
I can send firebase push notification successful and I can get parameter but I cant block notification.
How I can do it?
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
GADMobileAds.sharedInstance().start(completionHandler: nil)
FirebaseApp.configure()
// [START set_messaging_delegate]
Messaging.messaging().delegate = self
// [END set_messaging_delegate]
// Register for remote notifications. This shows a permission dialog on first run, to
// show the dialog at a more appropriate time move this registration accordingly.
// [START register_for_notifications]
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()
if(messageType == "some parameter"){
}
// [END register_for_notifications]
return true
}
If you dont want to receive push notifications then you just need to deny
notification permission when your app ask for that.
Or you could disable notifications by opening Settings -> Notifications, and then turning that app's notifications off.
You can use topics to send and receive specific type of notification. You can see
topics.
Unfortunately, you cannot block showing remote push notifications on iOS device. As it was said the backend should handle this.

Push notification when app is terminated

My app works fine with push notifications if the app was in the background and/or if the app is in the foreground.
The problem I have is if the app is terminated (which I force by double-click on the home button, find the app, and swipe up).
I am using ios 9 and swift 2.
In app delegate, didFinishLaunchingWithOptions, I do:
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
Then:
func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
application.registerForRemoteNotifications()
}
Followed by didRegisterForRemoteNotificationsWithDeviceToken & didFailToRegisterForRemoteNotificationsWithError.
Then, I am using the relatively new method:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {...}
According to the documentation and this link, as oppose to the old version of didReceiveRemoteNotification, this method is called if the app was terminated (as oppose to calling will/did finishLaunchingWithOptions).
However, if there was a push (which was received - I can see it on the screen) and I launch the app after it has been terminated, this method does not seem to be called as the code that handles the push (simply post a notification so it is picked up by the respective ViewController) does not get called.
What am I missing? Is there an additional check I need to do in didFinishLaunchingWithOptions? Somewhere else?
Managed to solve the problem of intercepting a Remote Push when the app is terminated for ios 9.1 with the following but it failed on 9.2 (random failure?):
Register for remote:
if #available(iOS 9, *) {
let settings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
// UIApplication.sharedApplication().registerUserNotificationSettings(settings)
//
// UIApplication.sharedApplication().registerForRemoteNotifications()
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
} else if #available(iOS 8.0, *){
register for 8...
} else { //ios 7
register for 7...
}
if let _ = launchOptions {
if let _ = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary {
handleRemotePush()
} else if let _ = launchOptions?[UIApplicationLaunchOptionsLocalNotificationKey] as? UILocalNotification {
handleLocalNots()
} else {
handleElse()
}
}

Resources