iOS Firebase推送通知:如何提供Firebase用户的设备令牌和发送通知

EQO*_*123 17 push-notification ios firebase

最近在谷歌I/O活动中谷歌重新装修了Firebase并增加了许多新功能,并触及了其余的功能.我一直在尝试通过Firebase将iOS推送通知实现到我的应用程序中,通过最基本的级别,所以我创建了一个非常简单的应用程序除了接收远程推送通知之外什么都不做.

在Firebase内部,我上传了我的证书,在Xcode中,我的配置文件已添加到目标和项目中,而在Firebase中我已上传了正确的证书.下面是我的AppDelegate.swift文件中包含的代码,但因为我ViewController.swift的"空",我没有包含它.

虽然没有崩溃或运行时错误,但当我加载应用程序时,我接受通知.然后,我退出应用程序并关闭我的设备.在Firebase中,我将通知发送到正确的应用.几分钟后,在Firebase中,它说通知是"已完成".

但是,我从未收到过设备上的通知.因此,总之,我需要一个解决方案来发送Firebase deviceToken,然后使用"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)

    }


}
Run Code Online (Sandbox Code Playgroud)

onm*_*133 31

更新:从Firebase 4.0.4开始,您可以关注https://github.com/onmyway133/blog/issues/64

APNS设备如何处理

我一直在阅读向iOS上的用户段发送通知,但没有提及APNS设备令牌,这对于推送通知至关重要.

所以Firebase必须在引擎盖下做一些调整.事实上它是.阅读后端文档下游消息给了我们这个想法

Swizzling disabled:映射您的APN令牌和注册令牌

If you have disabled method swizzling, you'll need to explicitly map your APNs token to the FCM registration token. Override the
Run Code Online (Sandbox Code Playgroud)

方法didRegisterForRemoteNotificationsWithDeviceToken来检索的APN令牌,然后调用setAPNSToken.

func application(application: UIApplication,
                   didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
  FIRInstanceID.instanceID().setAPNSToken(deviceToken, type: FIRInstanceIDAPNSTokenTypeSandbox)
}
Run Code Online (Sandbox Code Playgroud)

我特别努力避免尽可能多的调酒.阅读将适用于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
Run Code Online (Sandbox Code Playgroud)

适用时,本指南提供了启用和不启用方法调配的迁移示例.

给我看这个代码

有这个在你的 Podfile

pod 'Firebase'
pod 'FirebaseMessaging'
Run Code Online (Sandbox Code Playgroud)

这是完成的代码

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)
}
Run Code Online (Sandbox Code Playgroud)

  • 什么是`connectToFcm`用于?推送通知适用于`.setAPNSToken()`独自一人. (2认同)

San*_*pul 13

没有CocoaPods集成

首先阅读Firebase文档.=> Firebase文件

  1. 在Firebase上注册项目=>在此处注册项目

  2. 从这里获取GoogleService-Info.plist文件=> project => settings => General

  3. GoogleService-Info.plist文件会在您的项目中删除.

  4. 在Firebase中设置通知.p12证书(生产和开发)=> project => settings => Cloud Messaging

  5. 在此处下载Firebase SDK => Firebase SDK下载

  6. 在项目中创建SDK文件夹并在其中删除所有SDK文件夹.

  7. 现在在Xcode => libicucore.tbd中添加此框架

  8. 在Xcode中设置背景模式=>项目=>功能=>背景模式ON => RemoteNotification
  9. 添加Info.Plist文件FirebaseAppDelegateProxyEnabled设置BOOL 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]);

            });
        });


    }
}];
}
Run Code Online (Sandbox Code Playgroud)

  • 当iOS应用程序处于后台或前台模式时,此工作正常.但是,当iOS应用程序终止时它无效.当app杀死时,我无法收到推送通知. (2认同)
  • 不要在生产中使用它!没有人会在第一个应用程序启动时接受推送通知权限。 (2认同)

Shu*_*ank 5

现在iOS的FCM文档很差.

按照他们在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.")
      }
    }
  }
Run Code Online (Sandbox Code Playgroud)

现在您的令牌已发送到FCM服务器