I'm trying to set up silent push notifications between devices through Firebase's cloud messaging that will call a method upon being received when the app is inactive. Right now it works once, but when I try to push a notification again it doesn't work (I set up the method "doSomething()" to test it)
Sorry my AppDelegate's an absolute mess. Here is what I have:
App Delegate:
import UIKit
import Firebase
import UserNotifications
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {
var window: UIWindow?
static let notificationUrl = "https://gcm-http.googleapis.com/gcm/send"
static var deviceId = String()
static let serverKey = "[myServerKeyIsEnteredHere]"
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
Messaging.messaging().delegate = self
setPushNotifications(application)
return true
}
func setPushNotifications(_ 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()
UIApplication.shared.applicationIconBadgeNumber = 0
InstanceID.instanceID().instanceID { (result, error) in
if let error = error {
print("Error fetching remote instance ID: \(error)")
} else if let result = result {
print("Remote instance ID token from didRegisterForRemoteNotificationsWithDeviceToken: \(result.token)")
AppDelegate.deviceId = result.token
}
}
}
func application(received remoteMessage: MessagingRemoteMessage) {
print("remoteMessage:\(remoteMessage.appData)")
}
func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
doSomething()
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
Messaging.messaging().appDidReceiveMessage(userInfo)
doSomething()
print(userInfo)
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
print("message: \(userInfo)")
Messaging.messaging().appDidReceiveMessage(userInfo)
doSomething()
completionHandler(UIBackgroundFetchResult.newData)
}
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
guard let newToken = InstanceID.instanceID().token() else {return}
AppDelegate.deviceId = newToken
// 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 from didRefreshRegistrationToken: \(result.token)")
// AppDelegate.deviceId = result.token
// }
// }
connectToFCM()
}
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
let dataDict:[String: String] = ["token": fcmToken]
NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
connectToFCM()
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken
connectToFCM()
}
func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Failed to register: \(error)")
}
func connectToFCM() {
Messaging.messaging().shouldEstablishDirectChannel = true
Messaging.messaging().useMessagingDelegateForDirectChannel = true
}
func doSomething() {
if let userId = Auth.auth().currentUser?.uid {
let userRef = Database.database().reference().child("Users").child(userId)
let someValue = ["sent": "yep"] as [String : AnyObject]
userRef.updateChildValues(someValue)
}
}
}
extension AppDelegate : MessagingDelegate {
// Receive data message on iOS 10 devices.
func applicationReceivedRemoteMessage(_ remoteMessage: MessagingRemoteMessage) {
print("%@", remoteMessage.appData)
}
}
I'm sending the Message using AlamoFire:
var headers: HTTPHeaders = HTTPHeaders()
headers = ["Content-Type":"application/json","Authorization":"key=\(AppDelegate.serverKey)"]
let notification = ["to": deviceId,
"priority": "high",
"content_available": true,
"data": ["key1": "locationPush"]] as [String: Any]
Alamofire.request(AppDelegate.notificationUrl as URLConvertible, method: .post as HTTPMethod, parameters: notification, encoding: JSONEncoding.default, headers: headers).responseJSON { (response) in
print(response)
}