I'm using push notifications in my project with APNS.
The push notifications worked well before to add and config Firebase SDK.
I noticed that after to add Firebase the function: didRegisterForRemoteNotificationsWithDeviceToken is not called.
I don't know if there is something that I have to disable in Firebase, if I remove the Firebase set up (FirebaseApp.configure()) the functiondidRegisterForRemoteNotificationsWithDeviceToken is called again.
My code:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// ... existing code ...
registerForPushNotifications()
return true
}
func registerForPushNotifications() {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) {
(granted, error) in
print("Permission granted: \(granted)")
guard granted else { return }
}
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let tokenParts = deviceToken.map { data -> String in
return String(format: "%02.2hhx", data)
}
let token = tokenParts.joined()
print("Device Token: \(token)")
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Failed to register: \(error)")
}
Just turn off method swizzling in FCM: https://firebase.google.com/docs/cloud-messaging/ios/client#method_swizzling_in
Related
I have this code that asks the user to allow my app to receive push notes.
The permission part of it works fine but I never get a device token or any error after I allow the app to receive push notifications.
This is my AppDelegate file:
class AppDelegate: UIResponder, UIApplicationDelegate{
var window: UIWindow?
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions
launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
registerForPushNotifications()
let notificationOption = launchOptions?[.remoteNotification]
if
let notification = notificationOption as? [String: AnyObject],
let aps = notification["aps"] as? [String: AnyObject] {
(window?.rootViewController as? UITabBarController)?.selectedIndex = 1
}
return true
}
func registerForPushNotifications() {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
print("Permission granted: \(granted)")
guard granted else { return }
UNUserNotificationCenter.current().getNotificationSettings { (settings) in
print("Notification settings: \(settings)")
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
}
func getNotificationSettings() {
UNUserNotificationCenter.current().getNotificationSettings { (settings) in
print("Notification settings: \(settings)")
}
}
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let tokenParts = deviceToken.map { data -> String in
return String(format: "%02.2hhx", data)
}
let token = tokenParts.joined()
print("Device Token: \(token)")
}
func application(_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Failed to register: \(error)")
}
}
I've tried different variations of the same code and still getting no device token. Ive enabled the Push notifications in my project in Xcode and I restarted the my device a few times too.
EDIT:
The didRegisterForRemoteNotificationsWithDeviceToken and didFailToRegisterForRemoteNotificationsWithError are never called for some reason!
Because I am not getting any error or device token at all!
My app has push notifications enabled, and up until today they were working properly. From setting breakpoints I've realized that the issue is that didRegisterForRemoteNotificationsWithDeviceToken is no longer being called. This is confusing to me as my notifications code hasn't change since when it was working (yesterday). Here is what my AppDelegate looks like:
import UserNotifications
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
...
registerForPushNotifications()
return true
}
func registerForPushNotifications() {
UNUserNotificationCenter.current()
.requestAuthorization(options: [.alert, .sound, .badge]) {
[weak self] granted, error in
print("Permission granted: \(granted)")
guard granted else { return }
self?.getNotificationSettings()
}
}
func getNotificationSettings() {
UNUserNotificationCenter.current().getNotificationSettings { settings in
print("Notification settings: \(settings)")
guard settings.authorizationStatus == .authorized else { return }
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
let token = tokenParts.joined()
print("Device Token: \(token)")
global_device_token = token
}
The call to UIApplication.shared.registerForRemoteNotifications() in getNotificationSettings does get run however.
I created a simple empty iOS application with XCode 11.5.
With my device iOS 13.5.1, I am tying to implement push notifications but I dont receive the device push token or any error.
What am I doing wrong?
The method didRegisterForRemoteNotificationsWithDeviceToken is never called.
With following code:
import UIKit
import UserNotifications
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
registerForRemoteNotification()
return true
}
func registerForRemoteNotification() {
if #available(iOS 10.0, *) {
let center = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in
print("Authorization executed")
}
UIApplication.shared.registerForRemoteNotifications()
}
else {
UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.sound, .alert, .badge], categories: nil))
UIApplication.shared.registerForRemoteNotifications()
}
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
func application(
_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
let token = tokenParts.joined()
print("Device Token: \(token)")
}
func application(
_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Failed to register: \(error)")
}
}
I have following output in the console:
Requesting permission
2020-06-06 12:13:23 +0000
Authorization executed
Requesting permission
2020-06-06 12:13:24 +0000
...
...
...
Screenshot:
Before trying this, make sure you have added this Capabilities...
under 'Capabilities', (next to General),
- Push Notifications option is turned ON`
- and under Background Modes, Remote Notifications is turned ON
For me it took like 6 hours after I recived all tokens that I requested. It really can take a long time sometimes
Import the UserNotifications framework and add the UNUserNotificationCenterDelegate in AppDelegate.swift
Request user permission
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let notificationCenter = UNUserNotificationCenter.current()
notificationCenter.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
// Enable or disable features based on authorization.
}
notificationCenter.delegate = self
application.registerForRemoteNotifications()
return true
}
Getting device token
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
{
let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
print(deviceTokenString)
}
In case of error
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("i am not available in simulator \(error)")
}
In case if you need to know the permissions granted
UNUserNotificationCenter.current().getNotificationSettings(){ (settings) in
switch settings.soundSetting{
case .enabled:
print("enabled sound setting")
case .disabled:
print("setting has been disabled")
case .notSupported:
print("something vital went wrong here")
}
}
On Receiving notification following delegate will call:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
println("Recived: \(userInfo)")
//Parsing userinfo:
var temp : NSDictionary = userInfo
if let info = userInfo["aps"] as? Dictionary<String, AnyObject>
{
var alertMsg = info["alert"] as! String
var alert: UIAlertView!
alert = UIAlertView(title: "", message: alertMsg, delegate: nil, cancelButtonTitle: "OK")
alert.show()
}
}
In your case, I think you need to replace:-
let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
with,
let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
I am doing all the setting and certificate perfectly but private func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data). method not call at all.
If I off Push notification from capability it call didFailToRegisterForRemoteNotificationsWithError but when I on this it never call.
In didFinishLaunchingWithOptions here is my code
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UNUserNotificationCenter.current().delegate = self
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) {
(granted, error) in
print("Permission granted: \(granted)")
// 1. Check if permission granted
guard granted else { return }
// 2. Attempt registration for remote notifications on the main thread
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}
}
}
If I am doing something wrong, help. I have worked on this multiple time perfectly but this time , no idea. Help me.
I want to develop a simple code which use push notifications. I create certificates and provision profiles based on existing tutorials, such as link, and this, but the register function application:didRegisterForRemoteNotificationsWithDeviceToken: is not called at all, thus I can't get device token.
I also turned on Push notification and Remote notification for background in Capabilities tab in xcode. here is my code in AppDelegate.swift
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound]){ (granted, error) in }
UIApplication.shared.registerForRemoteNotifications()
return true
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
print("APNs device token: \(deviceTokenString)")
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("APNs registration failed: \(error)")
}
func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable : Any]) {
print("Push notification received: \(data)")
}
I am working with an iPhone 5s running iOS 10.3.2
Please call registerForNotifications from didFinishLaunchingWithOptions method in AppDelegate
//MARK:- Methods
func registerForNotifications(){
if #available(iOS 10.0, *) {
let center = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options:[.alert,.sound]) { (granted, error) in
if granted{
UIApplication.shared.registerForRemoteNotifications()
}else{
print("Notification permission denied.")
}
}
} else {
// For ios 9 and below
let type: UIUserNotificationType = [.alert,.sound];
let setting = UIUserNotificationSettings(types: type, categories: nil);
UIApplication.shared.registerUserNotificationSettings(setting);
UIApplication.shared.registerForRemoteNotifications()
}
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = String(format: "%#", deviceToken as CVarArg).trimmingCharacters(in: CharacterSet(charactersIn: "<>")).replacingOccurrences(of: " ", with: "")
print(token)
}
I couldn't find why it wasn't called, but when I changed my test target to an iPhone 7 which is running iOS 10.3.2, it worked fine.
I'm not sure why it is happening, but changing your target may solve the problem