Уведомления iOS Firebase Push: как указать токен устройства и отправить уведомление Firebase

Совсем недавно в мероприятии ввода-вывода Google Google обновила Firebase и добавила много новых функций и затронула оставшиеся. Я пытаюсь внедрить iOS Push Notifications через Firebase в мое приложение на самом базовом уровне. Поэтому я создал очень простое приложение, которое ничего не делает, кроме того, что вы получаете удаленные push-уведомления.

Внутри Firebase я загрузил свой сертификат, и в Xcode мои профили подготовки были добавлены как к цели, так и к проекту, а в Firebase я загрузил правильный сертификат. Ниже приведен код, содержащийся внутри моего файла AppDelegate.swift но поскольку мой ViewController.swift "пуст", я не включил его.

Несмотря на отсутствие сбоев или ошибок во время выполнения, при загрузке приложения я принимаю уведомления. Затем я выхожу из приложения и выключу свое устройство. В Firebase я отправляю уведомление в правильное приложение. Через пару минут в Firebase говорится, что уведомление было "Завершено".

Однако я никогда не получал уведомления на устройстве. Итак, в заключение, мне нужно решение для отправки Firebase this deviceToken а затем использовать "Уведомления Firebase" для отправки push-уведомления.

Любая помощь для моего кода или в целом была бы весьма признательна, и я надеюсь, что это поможет будущим зрителям. Спасибо! Мой код в AppDelegate.swift:

import UIKit
import Firebase
import FirebaseMessaging

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

        FIRApp.configure()

        let notificationTypes : UIUserNotificationType = [UIUserNotificationType.Alert, UIUserNotificationType.Badge, UIUserNotificationType.Sound]

        let notificationSettings = UIUserNotificationSettings(forTypes: notificationTypes, categories: nil)

        application.registerForRemoteNotifications()
        application.registerUserNotificationSettings(notificationSettings)

        return true
    }

    func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {

        print("Device Token: \(deviceToken)")

    }

    func applicationWillResignActive(application: UIApplication) {

    }

    func applicationDidEnterBackground(application: UIApplication) {

    }

    func applicationWillEnterForeground(application: UIApplication) {

    }

    func applicationDidBecomeActive(application: UIApplication) {

    }

    func applicationWillTerminate(application: UIApplication) {

    }

    func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {

        print("MessageID : \(userInfo["gcm.messgae_id"]!)") // or gcm_etc...

        print(userInfo)

    }


}

Ответы

Ответ 1

Обновлено: с Firebase 4.0.4 вы можете следовать https://github.com/onmyway133/blog/issues/64

КАК ОБРАЩАЕТСЯ УСТРОЙСТВО УСТРОЙСТВА APNS

Я читал Отправить уведомление на пользовательский сегмент в iOS, но нет упоминания о токене устройства APNS, что имеет решающее значение для отправки уведомлений.

Таким образом, Firebase должна совершать несколько зависаний под капотом. На самом деле это так. Чтение исходной документации Сообщения в нисходящем направлении дает нам идею

Swizzling отключено: отображение маркера APN и регистрационного токена

If you have disabled method swizzling, you'll need to explicitly map your APNs token to the FCM registration token. Override the

методы didRegisterForRemoteNotificationsWithDeviceToken для извлечения маркер APN, а затем вызовите setAPNSToken.

func application(application: UIApplication,
                   didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
  FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenTypeSandbox)
}

Я особенно стараюсь избегать swizzling как можно больше. Чтение Перенос приложения GCM Client для iOS для облачных сообщений Firebase дает нам, как его отключить

Включение/выключение метода swizzling

Метод swizzling, доступный с помощью FCM, упрощает ваш код клиента. Однако для разработчиков, которые предпочитают не использовать его, FCM позволяет вам отключить метод swizzling, добавив FIRMessagingAutoRegisterEnabledflag в файле Info.plist приложений и установив его значение NO (логическое значение).

FCM swizzling affects how you handle the default registration token, and how you handle downstream message callbacks. Where

в этом руководстве приведены примеры миграции как с помощью, так и с без возможности использования swizzling.

ПОКАЖИТЕ КОДЕКС

Сделайте это в своем Podfile

pod 'Firebase'
pod 'FirebaseMessaging'

Вот завершенный код

import Firebase
import FirebaseMessaging

override func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
  FIRApp.configure()

  NSNotificationCenter.defaultCenter().addObserver(self,
                                                   selector: #selector(tokenRefreshNotification(_:)),
                                                   name: kFIRInstanceIDTokenRefreshNotification,
                                                   object: nil)
}

// NOTE: Need to use this when swizzling is disabled
public func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {

  FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenType.Sandbox)
}

func tokenRefreshNotification(notification: NSNotification) {
  // NOTE: It can be nil here
  let refreshedToken = FIRInstanceID.instanceID().token()
  print("InstanceID token: \(refreshedToken)")

  connectToFcm()
}

func connectToFcm() {
  FIRMessaging.messaging().connectWithCompletion { (error) in
    if (error != nil) {
      print("Unable to connect with FCM. \(error)")
    } else {
      print("Connected to FCM.")
    }
  }
}

public func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
  print(userInfo)
}

Ответ 2

Интеграция без CocoaPods

Сначала прочтите Firebase Doc. = > Firebase Doc

  • Зарегистрируйте проект на Firebase здесь = > Зарегистрируйтесь здесь здесь

  • Получить файл GoogleService-Info.plist здесь = > project = > settings = > Общие

  • Папка GoogleService-Info.plist в вашем проекте.

  • установить Уведомление .p12 Сертификаты (производство и разработка) в Firebase  = > project = > settings = > Cloud Messaging

  • Загрузить Firebase SDK здесь = > Firebase SDK Загрузить

  • Создайте папку SDK в своем проекте и распакуйте в нее всю папку SDK.

  • Теперь добавьте эту структуру в свой Xcode = > libicucore.tbd

  • Установить фоновые режимы ВКЛ в Xcode = > Проекты = > Возможности = > Фоновый режим ВКЛ = > УдаленнаяNotification
  • Добавить в ваш файл Info.Plist FirebaseAppDelegateProxyEnabled Установить BOOL НЕТ.

введите описание изображения здесь

В Objective-c ваш файл Appdelegate.m

#import "AppDelegate.h"
#import "Firebase.h"
#import "AFNHelper.h"

@interface AppDelegate (){

    NSString *InstanceID;
}
@property (nonatomic, strong) NSString *strUUID;
@property (nonatomic, strong) NSString *strDeviceToken;
@end
@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    UIUserNotificationType allNotificationTypes =
    (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
    UIUserNotificationSettings *settings =
    [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    [[UIApplication sharedApplication] registerForRemoteNotifications];

    [FIRApp configure];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(tokenRefreshNotification:) name:kFIRInstanceIDTokenRefreshNotification object:nil];

    return YES;
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {

    NSLog(@"Message ID: %@", userInfo[@"gcm.message_id"]);
    [[FIRMessaging messaging] appDidReceiveMessage:userInfo];

    NSLog(@"userInfo=>%@", userInfo);
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {

    [[FIRInstanceID instanceID] setAPNSToken:deviceToken type:FIRInstanceIDAPNSTokenTypeProd];
    NSLog(@"deviceToken1 = %@",deviceToken);

}
- (void)tokenRefreshNotification:(NSNotification *)notification {
   NSLog(@"instanceId_notification=>%@",[notification object]);
    InstanceID = [NSString stringWithFormat:@"%@",[notification object]];

 [self connectToFcm];  
}

- (void)connectToFcm {

[[FIRMessaging messaging] connectWithCompletion:^(NSError * _Nullable error) {
    if (error != nil) {
        NSLog(@"Unable to connect to FCM. %@", error);
    } else {

        NSLog(@"InstanceID_connectToFcm = %@", InstanceID);
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

            dispatch_async(dispatch_get_main_queue(), ^{
                [self sendDeviceInfo];
                NSLog(@"instanceId_tokenRefreshNotification22=>%@",[[FIRInstanceID instanceID] token]);

            });
        });


    }
}];
}

Ответ 3

Документы для FCM для iOS сейчас довольно плохие.

Следуйте приложению , которое у них есть на github

Важная часть добавлена ​​здесь:

import Firebase
import FirebaseInstanceID
import FirebaseMessaging

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    // Register for remote notifications
    if #available(iOS 8.0, *) {
      let settings: UIUserNotificationSettings =
      UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
      application.registerUserNotificationSettings(settings)
      application.registerForRemoteNotifications()
    } else {
      // Fallback
      let types: UIRemoteNotificationType = [.Alert, .Badge, .Sound]
      application.registerForRemoteNotificationTypes(types)
    }

    FIRApp.configure()

    // Add observer for InstanceID token refresh callback.
    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.tokenRefreshNotificaiton),
        name: kFIRInstanceIDTokenRefreshNotification, object: nil)

    return true
  }

 func tokenRefreshNotificaiton(notification: NSNotification) {
    let refreshedToken = FIRInstanceID.instanceID().token()!
    print("InstanceID token: \(refreshedToken)")

    // Connect to FCM since connection may have failed when attempted before having a token.
    connectToFcm()
  }
  // [END refresh_token]

  // [START connect_to_fcm]
  func connectToFcm() {
    FIRMessaging.messaging().connectWithCompletion { (error) in
      if (error != nil) {
        print("Unable to connect with FCM. \(error)")
      } else {
        print("Connected to FCM.")
      }
    }
  }

Теперь ваш токен отправлен на сервер FCM