I can't get any push Notidication.
I tried to send a notification from Firebase console, to all the users of the app.
The Console says that the notification been sent to one device (my device), but I do not get anything on my iPhone.
I'm running this code at AppDelegate.swift:
//
// AppDelegate.swift
// mt
//
// Created by ES on 15.6.2018.
// Copyright © 2018 ES. All rights reserved.
//
import UIKit
import Firebase
import FirebaseMessaging
import UserNotifications
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
UIApplication.shared.applicationIconBadgeNumber = 0
registerForPushNotifications()
FirebaseApp.configure()
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler: #escaping (UIBackgroundFetchResult) -> Void) {
let dict = userInfo["aps"] as! NSDictionary
let title = dict["alert"]
print ("#", title!)
}
func registerForPushNotifications() {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) {
(granted, error) in
print("Permission granted: \(granted)")
guard granted else { return }
let viewAction = UNNotificationAction(identifier: "addToCal",
title: "New date available!",
options: [.foreground])
let newsCategory = UNNotificationCategory(identifier: "NEW_SESSION",
actions: [viewAction],
intentIdentifiers: [],
options: [])
UNUserNotificationCenter.current().setNotificationCategories([newsCategory])
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 -> 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 got the Token, so I think that my app have the permission to get notifications)
Related
How can I go to another view controller after successfully signing with google? I've tried "self.inputViewController?.performSegue(withIdentifier: "goToMain", sender: self)" in my App Delegate but not getting any respond. Am I supposed to add the method in App Delegate or the view controller with the sign-in button?
App Delegate
import UIKit
import Firebase
import GoogleSignIn
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate{
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
GIDSignIn.sharedInstance()?.clientID = "my_client_id"
GIDSignIn.sharedInstance()?.delegate = self
return true
}
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
if let error = error {
print(error)
return
}
guard
let authentication = user?.authentication,
let idToken = authentication.idToken
else {
return
}
let credential = GoogleAuthProvider.credential(withIDToken: idToken,
accessToken: authentication.accessToken)
Auth.auth().signIn(with: credential) { authResult, error in
if let error = error {
let authError = error as NSError
print(authError.localizedDescription)
return
}
self.inputViewController?.performSegue(withIdentifier: "goToMain", sender: self)
}
}
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return GIDSignIn.sharedInstance().handle(url)
}
// 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.
}
}
Are you sure about the inputViewController is not nil? This may a reason for not working.
You can add a function to test this, or you can use the print function to check, or, you can use debug point to check inputViewController is nil or not.
I'd like to add comment but I don't have enough reputation point :).
Good luck.
Am trying to fetch FCM key for push notification from Firebase cloud messaging but am getting nil & error which i mention below
**
Error :- APNS device token not set before retrieving FCM Token for Sender ID '836092823410'. Notifications to this FCM Token will not be delivered over APNS.Be sure to re-retrieve the FCM token once the APNS device token is set.
**
Google Plist File
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CLIENT_ID</key>
<string>836092823410-d76r5bkjrusfmgo6rskqo81l4mk7vmp4.apps.googleusercontent.com</string>
<key>REVERSED_CLIENT_ID</key>
<string>com.googleusercontent.apps.836092823410-d76r5bkjrusfmgo6rskqo81l4mk7vmp4</string>
<key>API_KEY</key>
<string>AIzaSyDpP1n_NRqj9c_Mq-pA2PlRez7AnVM5buw</string>
<key>GCM_SENDER_ID</key>
<string>836092823410</string>
<key>PLIST_VERSION</key>
<string>1</string>
<key>BUNDLE_ID</key>
<string>com.iai.tracker</string>
<key>PROJECT_ID</key>
<string>crucial-audio-334611</string>
<key>STORAGE_BUCKET</key>
<string>crucial-audio-334611.appspot.com</string>
<key>IS_ADS_ENABLED</key>
<false/>
<key>IS_ANALYTICS_ENABLED</key>
<false/>
<key>IS_APPINVITE_ENABLED</key>
<true/>
<key>IS_GCM_ENABLED</key>
<true/>
<key>IS_SIGNIN_ENABLED</key>
<true/>
<key>GOOGLE_APP_ID</key>
<string>1:836092823410:ios:0312dc35c45b23b9e37feb</string>
</dict>
</plist>
Delegate File
import UIKit
import GoogleMaps
import Firebase
import GooglePlaces
import Highcharts
enum BuildTypes: String {
case jsd = "JSD"
case fleetPolice = "FleetPolice"
case veyron = "Veyron"
case jbd = "JBD"
case gpsTracker = "GPSTracker"
case roadLookUp = "RoadLookUp"
case iaitrack = "IAITrack"
}
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, MessagingDelegate {
var window: UIWindow?
let gcmMessageIDKey = "gcm.message_id";
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
//Going through different build type
let buildType: String = Bundle.main.infoDictionary?["BUILD_TYPE"] as? String ?? "Debug"
print("Build type: - ",buildType)
NotificationCenter.default.addObserver(self, selector: #selector(self.notAuthorized), name: HTTPUtil.NotAuthorizedNotification, object: nil);
switch buildType {
case BuildTypes.jsd.rawValue, BuildTypes.fleetPolice.rawValue:
print("JSD")
GMSServices.provideAPIKey("AIzaSyBKsjff4VNWTyu8X3UTYXOBazO0jt_Cnpw");
GMSPlacesClient.provideAPIKey("AIzaSyBKsjff4VNWTyu8X3UTYXOBazO0jt_Cnpw");
case BuildTypes.veyron.rawValue, BuildTypes.jbd.rawValue, BuildTypes.gpsTracker.rawValue:
GMSServices.provideAPIKey("AIzaSyCRWtSQIUsoNhFwMMdeFRX0A74rooHskBg");
GMSPlacesClient.provideAPIKey("AIzaSyCRWtSQIUsoNhFwMMdeFRX0A74rooHskBg");
case BuildTypes.iaitrack.rawValue:
GMSServices.provideAPIKey("AIzaSyC2qDNCajLm1Kq_AuZTS5tE0xJ73R1RTkA");
GMSPlacesClient.provideAPIKey("AIzaSyC2qDNCajLm1Kq_AuZTS5tE0xJ73R1RTkA");
default:
print("REst")
GMSServices.provideAPIKey("AIzaSyAgaZm9nk4RcfgZ0O0R9UgxJ7PRLZt0RB4");
GMSPlacesClient.provideAPIKey("AIzaSyAgaZm9nk4RcfgZ0O0R9UgxJ7PRLZt0RB4");
}
FirebaseApp.configure()
Messaging.messaging().delegate = self
let t = Messaging.messaging().token { token, error in
if (token != nil) {
print(token)
} else {
print(error)
}
}
let token = Messaging.messaging().fcmToken
print("FCM token: \(token ?? "")")
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()
HIChartView.preload()
let u = UserService.getActiveUserLocalCache();
Configuration.setBaseUrl(baseUrl: u?.baseUrl ?? "https://api.fleethunt.in/");
return true
}
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
debugPrint(fcmToken);
}
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
// 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)
}
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
// 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)
completionHandler(UIBackgroundFetchResult.newData)
}
#objc func notAuthorized(){
if let window = self.window{
let mainTabController = window.rootViewController as! MainTabBarController;
mainTabController.selectedIndex = 0;
let home = (mainTabController.viewControllers?[0] as! UINavigationController).viewControllers[0] as! HomeViewController;
home.showLoginVC();
window.makeToast("Not Authorized. You have been logged out");
}
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
self.updateFcmToken();
let u = UserService.getActiveUserLocalCache();
Configuration.setBaseUrl(baseUrl: u?.baseUrl ?? "https://api.fleethunt.in/");
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
// This function is added here only for debugging purposes, and can be removed if swizzling is enabled.
// If swizzling is disabled then this function must be implemented so that the APNs token can be paired to
// the FCM registration token.
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
self.updateFcmToken();
// With swizzling disabled you must set the APNs token here.
// Messaging.messaging().apnsToken = deviceToken
}
func updateFcmToken() -> Void{
let mute = UserDefaults.standard.bool(forKey: "mute") ?? false
print(mute);
FCMService.updateFCM(mute: mute) { (resp) in
}
}
var orientationLock = UIInterfaceOrientationMask.portrait
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
return self.orientationLock
}
struct AppUtility {
static func lockOrientation(_ orientation: UIInterfaceOrientationMask) {
if let delegate = UIApplication.shared.delegate as? AppDelegate {
delegate.orientationLock = orientation
}
}
static func lockOrientation(_ orientation: UIInterfaceOrientationMask, andRotateTo rotateOrientation:UIInterfaceOrientation) {
self.lockOrientation(orientation)
UIDevice.current.setValue(rotateOrientation.rawValue, forKey: "orientation")
}
}
}
#available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {
// [START refresh_token]
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
print("Firebase registration token: \(fcmToken)")
self.updateFcmToken();
}
// [END refresh_token]
// [START ios_10_data_message]
// Receive data messages on iOS 10+ directly from FCM (bypassing APNs) when the app is in the foreground.
// To enable direct data messages, you can set Messaging.messaging().shouldEstablishDirectChannel to true.
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingDelegate) {
print("Received data message: \(remoteMessage.description)")
}
// [END ios_10_data_message]
// 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([])
}
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()
}
}
I am currently signing my user out like this:
print(GIDSignIn.sharedInstance()?.currentUser != nil) // true - signed in
GIDSignIn.sharedInstance()?.signOut()
print(GIDSignIn.sharedInstance()?.currentUser != nil) // false - signed out
Here is my is My AppDelegate
class AppDelegate: UIResponder, UIApplicationDelegate, GIDSignInDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
// Intializing Google Sign In...
GIDSignIn.sharedInstance().clientID = FirebaseApp.app()?.options.clientID
GIDSignIn.sharedInstance().delegate = self
GIDSignIn.sharedInstance().scopes = []
// FirebaseApp.app()?.options.clientID = "674329356626-ev6hn62oiqcj0o228nt85vv2bgroa45j.apps.googleusercontent.com"
return true
}
func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any])
-> Bool {
return GIDSignIn.sharedInstance().handle(url)
}
func sign(_ signIn: GIDSignIn!, didSignInFor user: GIDGoogleUser!, withError error: Error!) {
if error != nil{
print(error.localizedDescription)
return
}
let credential = GoogleAuthProvider.credential(withIDToken: user.authentication.idToken, accessToken: user.authentication.accessToken)
// Logging to Firebase...
Auth.auth().signIn(with: credential) { (res, err) in
if err != nil{
print((err?.localizedDescription)!)
return
}
// User Logged In Successfully...
// Sending Notification To UI...
NotificationCenter.default.post(name: NSNotification.Name("SIGNIN"), object: nil)
// Printing Email ID
print(res?.user.email)
}
// Check for sign in error
if let error = error {
if (error as NSError).code == GIDSignInErrorCode.hasNoAuthInKeychain.rawValue {
print("The user has not signed in before or they have since signed out.")
} else {
print("\(error.localizedDescription)")
}
return
}
// Post notification after user successfully sign in
NotificationCenter.default.post(name: .signInGoogleCompleted, object: nil)
}
// 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.
}
}
Sign in code:
GIDSignIn.sharedInstance()?.signIn()
Once the user is signed in, what is the best way for me to sign them out and prompt for them to sign in again? Please note that I am using the GoogleSignIn api.
Also note that I setup my google sign in functionality from here https://developers.google.com/identity/sign-in/ios/start?ver=swift
What seems to be happening in my app is the when my sign out function executes the current user is set to nil. However, when the user is signed out I can still access the data from the signed out user. I want the user to be able to sign out of their current account and sign into a new account for which I can access data from their newly signed in account.
My app should not retain data from the previous logged out user.
GIDSignIn.sharedInstance()?.signOut()
I also setup my google sign with firebase which seemed to help
I have created the Production Identifier and all this stuff and it has worked but sometime later suddenly it doesn't work anymore. And I have nothing changed in the Notification Area in my code.
From Firebase Cloud Messaging - Test Sending works fine. But from Device to Device not.
import UIKit
import Firebase
import FirebaseMessaging
import FirebaseInstanceID
import UserNotifications
import AVFoundation
import GoogleMobileAds
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?
static let NOTIFICATION_KEY = "https://gcm-http.googleapis.com/gcm/send"
static var DEVICE_ID = String()
static let SERVER_KEY = "AAAACucgXz8:APA91bE_vEyKiqR34sruY2f5tetjj_DrwVi42v9tL015tLEOZmwBh-q7oWsNXUrpR0S9XBCrbxMJtgUu70xNAyDeouNvxn1kHKll2Dcwzxbf40lbappxs-o6IDvHVvEajzX5Dzsq8MW8"
static var EXITAPP = Bool()
static var LIKESCOUNTER = Int()
var dateForm = DateFormatter()
var timeFormatter = DateFormatter()
static var INSERTTIME = false
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
FirebaseApp.configure()
window = UIWindow(frame: UIScreen.main.bounds)
window?.makeKeyAndVisible() //Damit wir die ganzen Views selber bearbeiten können.
window?.rootViewController = UINavigationController(rootViewController: ViewController())
if #available(iOS 10.0, *){
UNUserNotificationCenter.current().delegate = self
let option: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(options: option) { (bool, err) in
}
}
application.registerForRemoteNotifications()
UIApplication.shared.applicationIconBadgeNumber = 0
GADRewardBasedVideoAd.sharedInstance().load(GADRequest(), withAdUnitID: "ca-app-pub-3940256099942544/1712485313")
if #available(iOS 9.0, *){
application.isStatusBarHidden = true //HIDE STATUS BAR
}
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
insertOnlineActivity(online: false)
connectToFCM()
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
AppDelegate.EXITAPP = true
// if AppDelegate.INSERTTIME{
// insertLastLikedTime()
// }
insertOnlineActivity(online: false)
connectToFCM()
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
insertOnlineActivity(online: true)
connectToFCM()
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
insertOnlineActivity(online: true)
connectToFCM()
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String){
guard let newToken = InstanceID.instanceID().token() else {return}
AppDelegate.DEVICE_ID = newToken
connectToFCM()
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: #escaping () -> Void) {
let notification = response.notification.request.content.body
print(notification)
completionHandler()
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
guard let newToken = InstanceID.instanceID().token() else {return}
//let newToken = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
AppDelegate.DEVICE_ID = newToken
connectToFCM()
Messaging.messaging().setAPNSToken(deviceToken, type: .unknown)
}
func connectToFCM(){
Messaging.messaging().shouldEstablishDirectChannel = true
}
This is how I call the Notification
fileprivate func setUpPushNotifications(fromDeviceID: String){
let message = self.userName + " has sent you a voice message."
let title = "New Message"
let toDeviceID = fromDeviceID
var headers:HTTPHeaders = HTTPHeaders()
headers = ["Content-Type":"application/json","Authorization":"key=\(AppDelegate.SERVER_KEY)"]
let notifications = ["to" : "\(toDeviceID)" , "notification":["body":message,"title":title,"badge":1,"sound":"default"]] as [String : Any]
request(AppDelegate.NOTIFICATION_KEY as URLConvertible, method: .post as HTTPMethod, parameters: notifications, encoding: JSONEncoding.default, headers: headers).response { (response) in
print(response)
}
}
Hello there I receive notifications on iOS 9 but not on devices with
iOS 10 installed. What could be the problem?
import UIKit
import CoreData
import Firebase
import FirebaseMessaging
import UserNotifications
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate,UNUserNotificationCenterDelegate ,FIRMessagingDelegate {
public func applicationReceivedRemoteMessage(_ remoteMessage: FIRMessagingRemoteMessage) {
print(remoteMessage.appData)
}
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
UINavigationBar.appearance().barTintColor = UIColor(red: 50.0/255, green: 150.0/255, blue: 65.0/255, alpha: 1.0)
//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()
FIRApp.configure()
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)
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Registration failed!")
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
// Saves changes in the application's managed object context before the application terminates.
if #available(iOS 10.0, *) {
self.saveContext()
} else {
// Fallback on earlier versions
}
}
#available(iOS 10.0, *)
lazy var persistentContainer: NSPersistentContainer = {
/*
The persistent container for the application. This implementation
creates and returns a container, having loaded the store for the
application to it. This property is optional since there are legitimate
error conditions that could cause the creation of the store to fail.
*/
let container = NSPersistentContainer(name: "IndirimiKovala")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
// MARK: - Core Data Saving support
#available(iOS 10.0, *)
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
// 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)
}
}
2017-08-02 00:30:44.172 Indirimi Kovala[8086]
[Firebase/Analytics][I-ACS003016] Firebase Analytics App Delegate
Proxy is disabled. To log deep link campaigns manually, call the
methods in FIRAnalytics+AppDelegate.h. 2017-08-02 00:30:44.295:
FIRMessaging library version 1.2.2 2017-08-02
00:30:44.299 Indirimi Kovala[8086:863218] *** -[NSKeyedUnarchiver
initForReadingWithData:]: data is NULL 2017-08-02 00:30:44.331
Indirimi Kovala[8086] [Firebase/Analytics][I-ACS023007]
Firebase Analytics v.3700000 started 2017-08-02 00:30:44.333 Indirimi
Kovala[8086] [Firebase/Analytics][I-ACS023008] To enable
debug logging set the following application argument:
-FIRAnalyticsDebugEnabled (see ) Registration failed! 2017-08-02 00:30:44.389 [8086]
[Firebase/Analytics][I-ACS005000] The AdSupport Framework is not
currently linked. Some features will not function properly. Learn more
at 2017-08-02 00:30:44.402 Indirimi Kovala[8086]
[Firebase/Analytics][I-ACS023012] Firebase Analytics enabled
You need to implement the App Delegate method:
application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
This will get called when app is not in the foreground.
You are currently implementing:
userNotificationCenter(_ center: UNUserNotificationCenter, didReceive ...
but this one works when the app is in the foreground only.
Please implement below two methods
func application(_ application: UIApplication,didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
}
func application(_ application: UIApplication,didReceiveRemoteNotification userInfo: [AnyHashable: Any],fetchCompletionHandler completionHandler: #escaping(UIBackgroundFetchResult) -> Void) {
completionHandler(UIBackgroundFetchResult.newData)
}