Не могу получить уведомления FCM pu sh с моего сервера на iOS (работает на Android) - PullRequest
0 голосов
/ 08 января 2020

Я новичок в iOS / Swift и не могу получить уведомления pu sh. Я сконфигурировал свой серверный бэкэнд для уведомлений pu sh в мое приложение, когда происходит какое-либо действие. Я настроил уведомление данных через FCM, потому что мне нужны некоторые пользовательские данные в уведомлении, чтобы открыть одно действие / представление или другое. Это код, используемый для отправки уведомления (python / django):

registration_id = profiletarget.device_token
    message_title = "Ha llegado tu turno"
    message_body = "Entra y escribe en el relato para el que estás en cola"
    data_message = {
        "title" : "¿Listo para escribir?",
        "body" : "Ha llegado tu turno para escribir en el relato. Recuerda que tienes un minuto para aceptar tu turno y 3 para escribir.",
        "bookid" : booktarget.pk,
        "multimediaurl" : multimediaused.url
        }
    result = push_service.notify_single_device(registration_id=registration_id, data_message=data_message)

Все внутри этого кода работает, потому что я правильно получаю их на Android. Но на iOS ... я не могу заставить его работать.

У меня есть токен уведомлений, я отправляю его на свой сервер, я использую отправителя уведомлений на консоли FCM для отправки тестового пу Уведомления sh (iPhone получают их), но не те, что были в моем пользовательском методе. Ничего не отображается. Что-то не так в методе сервера или я что-то упустил?

Это код swift:

import UIKit
import KeychainSwift
import Firebase
import FirebaseMessaging

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {

    var window : UIWindow?;
    var storyboard : UIStoryboard?;
    var token = ""
    let gcmMessageIDKey = "gcm.message_id"


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        self.storyboard = UIStoryboard(name: "Main", bundle: Bundle.main);
        UITabBarItem.appearance().setTitleTextAttributes([NSAttributedString.Key.font: UIFont(name: "PT Sans", size: 12)!], for: .normal)
        UITabBarItem.appearance().setTitleTextAttributes([NSAttributedString.Key.font: UIFont(name: "PT sans", size: 12)!], for: .selected)
        let keychain = KeychainSwift()
        token = keychain.get("token") ?? ""
        if (token != ""){
            print("log-token: ", token)
            print("log-redirection: ", "no redirection needed!")
            FirebaseApp.configure()
            Messaging.messaging().delegate = self
            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()

        } else {
            print("log-token: ", "noToken")
            print("log-redirection: ", "redirection to LoginController")
            window?.rootViewController = self.storyboard?.instantiateViewController(withIdentifier: "loginView");
        }
        return true
    }

    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)")
        postNotificationToken(token: token)
    }

    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
      print("Firebase registration token: \(fcmToken)")

      let dataDict:[String: String] = ["token": fcmToken]
      NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)
      // TODO: If necessary send token to application server.
      // Note: This callback is fired at each app startup and whenever a new token is generated.
    }

    func postNotificationToken(token:String) {
        var request = URLRequest(url: URL(string: "https://myurl?myparam="+token)!)
        request.httpMethod = "GET"
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("Bearer "+self.token, forHTTPHeaderField: "myauth")

        let session = URLSession.shared
        let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in
            let httpURLResponse = response as? HTTPURLResponse;
            if (httpURLResponse?.statusCode == 200){
                let string = String.init(data: data!, encoding: String.Encoding.utf8)
                print(string)
            } else {
                print(httpURLResponse?.statusCode)
            }
        })

        task.resume()
    }



    func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
        print("Received data message: \(remoteMessage.appData)")
    }

    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void)
    {
        completionHandler([.alert, .badge, .sound])
    }


    // MARK: UISceneSession Lifecycle


}

Это мои целевые возможности:

Project target capabilities

И это мой ключ для уведомлений APN в моей учетной записи разработчика:

APN Key

С консолью FCM, уведомления Все в порядке:

FCM Console

Спасибо за чтение этого длинного поста. Все поможет!

Ответы [ 3 ]

0 голосов
/ 08 января 2020

Change The info plist according to this

Попробуйте отправить этот тип пользовательского формата с пользовательской полезной нагрузкой

примечание: это node.js код

    let message = {
    tokens: iosTokens,
    notification: {
        title: "title",
        body: "",
    },data = {
    "title" : "¿Listo para escribir?",
    "body" : "Ha llegado tu turno para escribir en el relato. Recuerda que tienes un minuto para aceptar tu turno y 3 para escribir.",
    "bookid" : booktarget.pk
    },apns : {
        payload: {
            aps: {
                mutableContent: true,
                contentAvailable: true,
                category: "CustomSamplePush",
                alert: {
                    launchImage: "imageURL.jpeg",
                    sound: "default"
                }
            }

        }
    }
}; 
0 голосов
/ 09 января 2020

Хорошо, у меня все работает, смешивая некоторые ответы и код, найденный в других постах. Во-первых, я использую ключ APN, а не сертификаты APN.

Во-вторых, я проверяю, в какой ОС есть пользователь, которому нужно отправить уведомление (iOS / Android), чтобы я мог настроить различные структура уведомлений. Это система уведомлений в python / django, использующая библиотеку PyFCM и отправляющая уведомление iOS как предупреждение, как я обнаружил в этом сообщении :

if devicetype == "and":
        registration_id = profiletarget.device_token
        message_title = "default-title"
        message_body = "default-body"
        data_message = {
            "title" : "title",
            "body" : "body",
            "bookid" : booktarget.pk,
            "multimediaurl" : multimediaused.url
            }
        result = push_service.notify_single_device(registration_id=registration_id, data_message=data_message)
    else:
        registration_id = profiletarget.device_token
        message_title = "title"
        message_body = "body"
        data_message = {
            "bookid" : booktarget.pk,
            "multimediaurl" : multimediaused.url,
            }
        result = push_service.notify_single_device(registration_id=registration_id,
                                   message_title=message_title,
                                   message_body=message_body,
                                   data_message=data_message,
                                   extra_kwargs={"apns_push_type": "alert"}
                                   )

Только в Xcode I пришлось рекламировать возможности для уведомлений pu sh и фонового режима - удаленных уведомлений, как указано в вопросе pi c.

В коде я пропустил некоторую часть учебника Firebase, соответствующую этим методам:

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["body"] {
        print("Notif metod 1")
//        gotoWritting(bookid: messageID)
      }

      // Print full message.
      print("Notif metod 1")
    }

    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["body"]{
        print("Notif metod 2")
//        gotoWritting(bookid: messageID)
      }

      // Print full message.
      print(userInfo["bookid"]!)
        gotoWritting(bookid: Int(userInfo["bookid"]! as! String) ?? 90)
      completionHandler(UIBackgroundFetchResult.newData)
    }

Второй - тот, который вызывается щелчком уведомления (фон, передний план и приложение закрываются ...), и после его нажатия я могу перенаправить пользователя с некоторыми параметрами уведомления.

Я не могу проверить предыдущую версию, но надеюсь, что она работает на iOS 9 до (Если вы знаете, работает это или нет, дайте мне знать, пожалуйста).

Спасибо всем, кто помог!

0 голосов
/ 08 января 2020

Вы настроили сертификат приложения с уведомлениями pu sh? 100

iOS Push notifications

Также вам нужно будет настроить проект в Xcode, выбрать одну из ваших целей и go to -> Войти и возможности и добавить возможность Pu sh Уведомления для каждой цели, толчки не работают в симуляторе, видимом, но метод didReceiveRemoteNotification сработав, вы можете отладить некоторые журналы или точки останова, если вы их получаете.

...