FCM Silent notification only works once (Swift)

2019-08-31 05:02发布

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)
    }

0条回答
登录 后发表回答