web-dev-qa-db-ja.com

iOS Firebaseプッシュ通知:Firebaseユーザーのデバイストークンを与えて通知を送信する方法

つい最近、Google I/OイベントでGoogleはFirebaseを刷新し、多くの新機能を追加し、残りの機能を修正しました。私は、Firebase経由でiOSプッシュ通知を最も基本的なレベルでアプリに実装しようとしてきたので、リモートプッシュ通知を受信する以外に何もしない非常にシンプルなアプリを作成しました。

Firebaseの内部で、証明書をアップロードし、Xcodeでプロビジョニングプロファイルをターゲットとプロジェクトの両方に追加し、Firebaseで正しい証明書をアップロードしました。以下はAppDelegate.Swiftファイル内に含まれるコードですが、ViewController.Swiftが「空」であるため、含めませんでした。

クラッシュやランタイムエラーはありませんが、アプリを読み込むときに通知を受け入れます。次に、アプリを終了し、デバイスの電源を切ります。 Firebaseでは、正しいアプリに通知を送信します。数分後、Firebaseでは通知が「完了」したと表示されます。

しかし、デバイスで通知を受け取ったことはありません。そのため、結論として、このdeviceTokenをFirebaseに送信し、「Firebase Notifications」を使用してプッシュ通知メッセージを送信するソリューションが必要です。

私のコードまたは一般的な支援は大歓迎であり、これが将来の視聴者にも役立つことを願っています。ありがとうございました! 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)

    }


}
17
EQOxx123

更新:Firebase 4.0.4の時点で、次の手順に従うことができます https://github.com/onmyway133/blog/issues/64

APNSデバイストークンの方法IS HANDLED

iOSのユーザーセグメントへの通知の送信 を読んでいますが、プッシュ通知に不可欠なAPNSデバイストークンについては言及していません。

そのため、Firebaseはボンネットの下でスウィズルをしているに違いありません。実際にそうです。バックエンドドキュメントを読む ダウンストリームメッセージ

Swizzling無効:APNsトークンと登録トークンのマッピング

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

メソッドdidRegisterForRemoteNotificationsWithDeviceTokenはAPNsトークンを取得し、setAPNSTokenを呼び出します。

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

私は特にスウィズルを可能な限り避けるようにしています。読み取り iOS用GCMクライアントアプリをFirebase Cloud Messagingに移行する 無効にする方法を示します

メソッドのスウィズルの有効化/無効化

FCMで利用可能なメソッドスウィズリングは、クライアントコードを簡素化します。ただし、使用しないことを好む開発者向けに、FCMでは、アプリのInfo.plistファイルにFIRMessagingAutoRegisterEnabledflagを追加して設定することにより、メソッドスウィズルを無効にできます。 NO(ブール値)への値。

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

該当する場合、このガイドでは、メソッドスウィズリングを有効または無効にした移行の例を示します。

コードを表示する

これを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)
}
31
onmyway133

CocoaPodsなしで統合

最初のFirebase Docの読み取り=> Firebase Doc

  1. Firebaseでプロジェクトをここに登録=> ここにプロジェクトを登録

  2. ここからGoogleService-Info.plistファイルを取得=>プロジェクト=>設定=>一般

  3. GoogleService-Info.plistファイルがプロジェクトにドロップされます。

  4. firebase => project => settings => Cloud Messagingで通知.p12証明書(生産および開発)を設定します

  5. Firebase SDKのダウンロードはこちら=> Firebase SDKダウンロード

  6. プロジェクトにSDKフォルダーを作成し、その中にすべてのSDKフォルダーをドロップします。

  7. Xcodeにこのフレームワークを追加します=> libicucore.tbd

  8. Xcodeでバックグラウンドモードをオンにする=>プロジェクト=>機能=>バックグラウンドモードをオンにする=> RemoteNotification
  9. Info.Plistファイルに追加FirebaseAppDelegateProxyEnabledBOOLを設定[〜#〜] no [〜#〜]

enter image description here

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]);

            });
        });


    }
}];
}
13
Sanandiya Vipul

現在、iOS用FCMのドキュメントはかなり貧弱です。

Githubにある sample アプリに従ってください

ここに追加された重要な部分:

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サーバーに送信されました

5
Shubhank