Hello I'm making an iPhone app where I send push notifications via Google's Firebase. I'm using Swift and Xcode for the programming. When I open the app I get asked to allow push notifications, however I don't receive any when I send them from the Firebase Console. I was wondering if you could help me out. I'm using Ad Hoc export to transfer an .isa to my friend's iPhone and test it that way. I followed exactly the Firebase tutorial - adding the .plist, the cocoa pod and I uploaded a certificate in the project settings. I have a paid apple developer account.
import UIKit
import CoreData
import Firebase
import FirebaseMessaging
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
FIRApp.configure()
let notificationTypes: UIUserNotificationType = [UIUserNotificationType.Alert,UIUserNotificationType.Badge,UIUserNotificationType.Sound]
let notificationSettings = UIUserNotificationSettings(forTypes:notificationTypes, categories:nil)
application.registerForRemoteNotifications()
application.registerUserNotificationSettings(notificationSettings)
return true
}
func applicationWillResignActive(application: UIApplication) {
}
func applicationDidEnterBackground(application: UIApplication) {
}
func applicationWillEnterForeground(application: UIApplication) {
}
func applicationDidBecomeActive(application: UIApplication) {
}
func applicationWillTerminate(application: UIApplication) {
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject],
fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
print("MessageID : \(userInfo["gcm_message_id"]!)")
print("%#", userInfo)
}
}
There are a few more things you need to do. When you registerForRemoteNotifications, you receive an APNS Token which you need to give to Firebase. This is done in application didRegisterForRemoteNotificationsWithDeviceToken.
import UIKit
import CoreData
import Firebase
import FirebaseMessaging
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
override init() {
super.init()
FIRApp.configure()
}
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
application.registerForRemoteNotifications()
application.registerUserNotificationSettings(
UIUserNotificationSettings(
forTypes: [.Alert, .Badge, .Sound],
categories: nil
)
)
NSNotificationCenter.defaultCenter().addObserver(self,
selector: #selector(tokenRefreshNotification),
name: kFIRInstanceIDTokenRefreshNotification,
object: nil
)
return true
}
func applicationDidEnterBackground(application: UIApplication) {
FIRMessaging.messaging().disconnect()
}
func applicationDidBecomeActive(application: UIApplication) {
FIRMessaging.messaging().connectWithCompletion { (error) in
switch error {
case .Some:
print("Unable to connect with FCM. \(error)")
case .None:
print("Connected to FCM.")
}
}
}
func applicationWillResignActive(application: UIApplication) {}
func applicationWillEnterForeground(application: UIApplication) {}
func applicationWillTerminate(application: UIApplication) {}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: .Sandbox)
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject],
fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
print("MessageID : \(userInfo["gcm.message_id"]!)")
print("%#", userInfo)
}
func tokenRefreshNotification(notification: NSNotification) {
if let refreshedToken = FIRInstanceID.instanceID().token() {
print("Instance ID token: \(refreshedToken)")
}
applicationDidBecomeActive(UIApplication.sharedApplication())
}
}
Related
Everything works fine after the second time. this issue only occurs once per device, making it hard to debug.
Even if I restarted the device issue doesn't appear again but as it always happens for new users the first time.
AppDelegate.Swift
import UIKit
import Flutter
import flutter_downloader
import Firebase
#UIApplicationMain
#objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
FlutterDownloaderPlugin.setPluginRegistrantCallback(registerPlugins)
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}
if(!UserDefaults.standard.bool(forKey: "Notification")) {
UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
UserDefaults.standard.set(true, forKey: "Notification")
}
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
override func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
super.application(application, didReceiveRemoteNotification: userInfo, fetchCompletionHandler: completionHandler)
let firebaseAuth = Auth.auth()
Messaging.messaging().appDidReceiveMessage(userInfo)
print(userInfo)
if (firebaseAuth.canHandleNotification(userInfo)){
completionHandler(.noData)
return
}
}
}
private func registerPlugins(registry: FlutterPluginRegistry) {
if (!registry.hasPlugin("FlutterDownloaderPlugin")) {
FlutterDownloaderPlugin.register(with: registry.registrar(forPlugin: "FlutterDownloaderPlugin")!)
}
}
Crash Log:
specialized AppDelegate.application(_:didReceiveRemoteNotification:fetchCompletionHandler:) + 600 (AppDelegate.swift:29)
I'm using Swift4:
I want to create firebase push notification, i'd follow steps as this video firebase push notification
and this is the app delegate code:
import UIKit
import IQKeyboardManagerSwift
import FBSDKLoginKit
import TwitterKit
import Firebase
import FirebaseMessaging
import FirebaseInstanceID
import UserNotifications
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
print("user tooooken: ", Common.getUserToken())
FirebaseApp.configure()
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { (success, error) in
if(error == nil) {
print("successful authentication")
}
}
application.registerForRemoteNotifications()
NotificationCenter.default.addObserver(self, selector: #selector(self.refreshToken(notification:)), name: NSNotification.Name.InstanceIDTokenRefresh, object: nil)
UIApplication.shared.statusBarView?.backgroundColor = UIColor(red:255/255.0, green:51/255.0, blue:255/255.0, alpha: 1.0);
UINavigationBar.appearance().tintColor = UIColor.white
UINavigationBar.appearance().titleTextAttributes = [NSAttributedStringKey.foregroundColor:UIColor.white]
TWTRTwitter.sharedInstance().start(withConsumerKey:"xxxxxxxxxxx", consumerSecret:"xxxxxxxxxxxxxxxxxx")
return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
}
func applicationWillResignActive(_ application: UIApplication) {
FBSDKAppEvents.activateApp()
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
return FBSDKApplicationDelegate.sharedInstance().application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
}
func applicationDidEnterBackground(_ application: UIApplication) {
Messaging.messaging().shouldEstablishDirectChannel = false
}
func applicationDidBecomeActive(_ application: UIApplication) {
FBHandler()
}
///// Twitter authentication //////
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
if TWTRTwitter.sharedInstance().application(app, open: url, options: options) {
return true
}
return true
}
#objc func refreshToken(notification: NSNotification) {
let refreshToken = InstanceID.instanceID().token()!
print(refreshToken)
FBHandler()
}
func FBHandler() {
Messaging.messaging().shouldEstablishDirectChannel = true
}
}
when I push notification from firebase server it delivered successfully to the device, but when the php server sent push notification it doesn't work, is i forget any step ?
Make sure these:
you have sent firebase FCM token of your device to your server.
If your server sent you a data notification then it's data object
should be in 'notification' key.
Also when user logout from device you should have to delete user's FCM
token from server.
I've used apple push notification service in my app and I received certificates and it works well But now my problem is that when I use Firebase rest API for sending message as notification I won’t receive any notification in my iPhone until I run the app But when I use Firebase it will be working, well here is my codes:
import UIKit
import Firebase
import FirebaseMessaging
import FirebaseInstanceID
import UserNotifications
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
NotificationCenter.default.addObserver(self, selector: #selector(self.refreshToken(notification:)), name: NSNotification.Name.InstanceIDTokenRefresh, object: nil)
Messaging.messaging().isAutoInitEnabled = true
FirebaseApp.configure()
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert , .badge , .sound]) { (success, error) in
}
} else {
UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil))
UIApplication.shared.registerForRemoteNotifications()
// Fallback on earlier versions
}
application.registerForRemoteNotifications()
return true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
#if PROD_BUILD
FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: .prod)
#else
InstanceID.instanceID().setAPNSToken(deviceToken, type: .sandbox)
#endif
Messaging.messaging().subscribe(toTopic: "global")
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
Messaging.messaging().subscribe(toTopic: "global")
print(userInfo)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
Messaging.messaging().appDidReceiveMessage(userInfo)
if Messaging.messaging().fcmToken != nil {
Messaging.messaging().subscribe(toTopic: "global")
}
// Print full message.
print(userInfo)
completionHandler(UIBackgroundFetchResult.newData)
}
func applicationDidEnterBackground(_ application: UIApplication) {
Messaging.messaging().shouldEstablishDirectChannel = false
}
func applicationDidBecomeActive(_ application: UIApplication) {
FBHandler()
}
#objc func refreshToken(notification : NSNotification) {
let refreshToken = InstanceID.instanceID().token()!
print("***\(refreshToken)")
FBHandler()
}
func FBHandler() {
Messaging.messaging().shouldEstablishDirectChannel = true
}
}
For APNS to work in background you need to enable background modes in capabilities section and tick remote notification.
Once you done add/check this delegate method in AppDelegate class
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
print("APNS USER INFO: \(userInfo)")
}
This method fires when app is in background and APNS comes.
More Info: How to handle push notification in background in ios 10?
UPDATE:
Add this one also and let see if it works
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: #escaping () -> Void) {
print("APNS: \(response.notification.request.content.userInfo)")
}
I'm trying to add action button for push notification. Actually, It is adding successfully when I build the app and give permission for notifications first time.
The problem begins after when I killed the app and trying to send notification again. Notification is receiving but action button doesn't appear. I think I don't define setNotificationCategories() method in right place but I can't find right solution for this issue. Here is my code: (Thanks for any help)
AppDelegate:
import UIKit
import UserNotifications
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate{
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound]) {(granted, error) in
if !granted {
print("Notification access denied.")
}
setNotificationCategory()
}
if #available(iOS 10.0, *) {
setNotificationCategory()
UNUserNotificationCenter.current().delegate = self
}
return true
}
func applicationWillResignActive(_ application: UIApplication) {
}
func applicationDidEnterBackground(_ application: UIApplication) {
}
func applicationWillEnterForeground(_ application: UIApplication) {
}
func applicationDidBecomeActive(_ application: UIApplication) {
}
func applicationWillTerminate(_ application: UIApplication) {
}
}
#available(iOS 10.0, *)
extension AppDelegate: UNUserNotificationCenterDelegate{
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
if response.notification.request.content.categoryIdentifier == Constants.Notification.Category.general{
if response.actionIdentifier == Constants.Notification.Action.likeAction{
if let notificationID = response.notification.request.content.userInfo["notification_id"]{
NotificationActionHandler.likeActionHandler(notificationID: notificationID as! Int)
}
}
}
completionHandler()
}
func setNotificationCategory(){
let likeAction = UNNotificationAction(identifier: Constants.Notification.Action.likeAction, title: "❤️", options: [])
let generalCategory = UNNotificationCategory(identifier: Constants.Notification.Category.general, actions: [likeAction], intentIdentifiers: [], options: .customDismissAction)
let center = UNUserNotificationCenter.current()
center.setNotificationCategories([generalCategory])
}
}
NotificationActionHandler:
import Foundation
class NotificationActionHandler{
class func likeActionHandler(notificationID: Int){
print("liked! ❤️ \(notificationID)")
}
}
I have created app with notification. When i send notification on developer mode then i get notifications. but when i send on release mod i don't get anything. I read that i should change certificate to product certificat. But it doesn't helped. here is my appdelegate:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FIRApp.configure()
let notificationTypes : UIUserNotificationType = [.alert, .badge, .sound]
let notificationSettings : UIUserNotificationSettings = UIUserNotificationSettings(types: notificationTypes, categories: nil)
application.registerForRemoteNotifications()
application.registerUserNotificationSettings(notificationSettings)
return true
}
private func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) {
FIRMessaging.messaging().subscribe(toTopic: "/topics/main")
}
private func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData)
{
FIRInstanceID.instanceID().setAPNSToken(deviceToken as Data, type: FIRInstanceIDAPNSTokenType.prod)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
print(userInfo["gcm.message_id"]!)
print(userInfo)
}
func application(_ application: UIApplication, dirtings: UIUserNotificationSettings)
{
UIApplication.shared.registerForRemoteNotifications()
}
func tokenRefreshNotification(notification: NSNotification) {
if let refreshedToken = FIRInstanceID.instanceID().token() {
print("InstanceID token: \(refreshedToken)")
}
// Connect to FCM since connection may have failed when attempted before having a token.
connectToFcm()
}
func connectToFcm() {
FIRMessaging.messaging().connect { (error) in
if (error != nil) {
print("Unable to connect with FCM. \(error)")
} else {
print("Connected to FCM.")
}
}
}
private func applicationDidEnterBackground(application: UIApplication) {
FIRMessaging.messaging().disconnect()
print("Disconnected from FCM.")
}
Just went through this,
I turned push off and deleted the certs from apple dev center and created them all over again and this made everything work as it should.
I also had this line of code set to,
FIRInstanceID.instanceID().setAPNSToken(deviceToken as Data, type: FIRInstanceIDAPNSTokenType.sandbox)
I will change it to .prod when I push to the app store.
I found solution. problem was with prod certificate. i forget to add prod cetificate to firebase.