つい最近、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)
}
}
更新: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)
}
最初のFirebase Docの読み取り=> Firebase Doc
Firebaseでプロジェクトをここに登録=> ここにプロジェクトを登録
ここからGoogleService-Info.plistファイルを取得=>プロジェクト=>設定=>一般
GoogleService-Info.plistファイルがプロジェクトにドロップされます。
firebase => project => settings => Cloud Messagingで通知.p12証明書(生産および開発)を設定します
Firebase SDKのダウンロードはこちら=> Firebase SDKダウンロード
プロジェクトにSDKフォルダーを作成し、その中にすべてのSDKフォルダーをドロップします。
Xcodeにこのフレームワークを追加します=> libicucore.tbd
- Xcodeでバックグラウンドモードをオンにする=>プロジェクト=>機能=>バックグラウンドモードをオンにする=> RemoteNotification
- Info.Plistファイルに追加FirebaseAppDelegateProxyEnabledBOOLを設定[〜#〜] no [〜#〜]。
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]);
});
});
}
}];
}
現在、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サーバーに送信されました