iOS Firebase推送通知:如何给Firebase用户';s设备令牌并发送通知

iOS Firebase推送通知:如何给Firebase用户';s设备令牌并发送通知,ios,push-notification,firebase,Ios,Push Notification,Firebase,最近在谷歌I/O活动上,谷歌对Firebase进行了翻新,添加了许多新功能,并对其余的功能进行了改进。我一直在尝试通过Firebase将iOS推送通知通过最基本的级别实现到我的应用程序中,因此我创建了一个非常简单的应用程序,除了接收远程推送通知之外,它实际上什么都不做 在Firebase内部,我上传了我的证书,在Xcode中,我的配置文件已添加到目标和项目中,在Firebase中,我上传了正确的证书。下面是我的AppDelegate.swift文件中包含的代码,但因为我的ViewControll

最近在谷歌I/O活动上,谷歌对Firebase进行了翻新,添加了许多新功能,并对其余的功能进行了改进。我一直在尝试通过Firebase将iOS推送通知通过最基本的级别实现到我的应用程序中,因此我创建了一个非常简单的应用程序,除了接收远程推送通知之外,它实际上什么都不做

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

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

但是,我从未在设备上收到通知。总之,我需要一个解决方案来发送Firebase this
deviceToken
,然后使用“Firebase通知”发送推送通知消息

任何对我的代码或一般的帮助都将不胜感激,我希望这对未来的观众有所帮助。非常感谢。
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)

    }


}

现在,对于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.")
      }
    }
  }
现在,您的令牌已发送到FCM服务器

Integrate而不使用CoCoapod 首先读取Firebase文档。=>

  • 在Firebase上注册项目=>

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

  • GoogleService-Info.plist文件放入项目中

  • 设置通知。Firebase中的p12证书(生产和开发) =>项目=>设置=>云消息传递

  • 在此处下载Firebase SDK=>

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

  • 现在在Xcode=>libicucore.tbd中添加这个框架

  • 在Xcode=>Projects=>Capabilities=>backgroundmodeon=>RemoteNotification中打开后台模式

  • 添加您的Info.Plist文件FirebaseAppDelegateProxyEnabled设置BOOLNO

  • 在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]);
                    
                });
            });
            
            
        }
    }];
    }
    

    更新:从Firebase 4.0.4开始,您可以

    如何处理APNS设备令牌

    我一直在阅读,但没有提到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
    
    方法
    didRegisterForRemotonificationsWithDeviceToken
    检索 输入APNs令牌,然后调用
    setAPNSToken

    我特别尽量避免喝太多的酒。阅读给了我们如何去做

    启用/禁用方法swizzling

    FCM提供的方法swizzling简化了客户端代码。 但是,对于不喜欢使用它的开发人员,FCM允许您 通过添加 应用程序的Info.plist文件中的firmMessageAutoRegisterEnabledFlag,以及 将其值设置为“否”(布尔值)

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

    显示代码

    在您的
    pod文件中保存此文件

    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)
    }
    

    “关闭我的设备。”呃,如果设备已关闭,您如何接收通知?您的意思是在重新打开设备后未收到通知吗?这是预期的行为。因此,在我的iPhone上,我第一次打开应用程序。我接受启用通知弹出窗口。然后我退出应用程序并将其关闭。我所期待的是,当通知通过时,通知会出现在您的锁屏上,然后点亮锁屏,但什么也没有发生。如果您关闭设备,没有锁屏,如果它关闭,怎么会有锁屏?如果你把它关掉,就没有电了。所以我不明白你在说什么,当你一直说关掉它。到底关闭什么?不管怎样,除此之外,假设设备已打开,但您仍然没有得到推送。您的代码在任何地方都无法获取推送令牌。因此,您是如何向firebase提供推送令牌的?这就是我有点困惑的地方。我认为不需要设备令牌,firebase会将通知发送给拥有该应用程序的所有人。当我说“关”的时候,我不是指一路断电,而是指你可以向左滑动并输入密码的地方。谢谢。谢谢,但是我在调用选择器时遇到一个错误:#selector您需要使用xcode 7.3作为#选择器语法。否则,您可以尝试
    选择器:“self.tokenRefreshNotification:”
    我已经实现了上述代码,还将p12设置为firebase->Settings->Cloud Messaging,是的,我可以在firebase->notification->New Message时获得推送通知…..但是self.ref.child(“messages”).childByAutoId().setValue(mdata)未收到推送通知…您应该将此作为单独的问题@Idevelopers提问,但您有什么想法吗?我这样做并检查了。我以为我收到过一次通知,但无法再次收到。检查我在这里发布的问题,我在其中输入了我的全部代码:当iOS应用程序处于后台或前台模式时,这可以正常工作。但当iOS应用程序终止时,它不起作用。我无法收到推送通知
    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)
    }