iOS集成Firebase云消息传递(FCM)

简介

Firebase 云消息传递 (FCM) 是一种跨平台消息传递解决方案,可供您免费、可靠地传递消息。
使用 FCM,您可以通知客户端应用有新的电子邮件或其他数据有待同步。您可以发送通知消息进行用户再互动并留住他们。在即时通讯等使用情形中,一条消息可将最多 4KB 的有效负载传送至客户端应用。

工作原理

FCM 实现包括用于发送和接收的两个主要组件:

  1. 一个受信任的环境,例如 Cloud Functions for Firebase 或用于构建、定位和发送消息的应用服务器。
  2. 一个接收消息的 iOS、Android 或网页 (JavaScript) 客户端应用。

您可以通过 Firebase Admin SDKFCM 服务器协议发送消息。为了利用强大的内置定位和分析功能来测试或发送营销或互动消息,您还可以使用通知编辑器

image.png

集成云消息传递:

准备工作:
*   安装 Xcode 10.1 或更高版本。
*   安装 CocoaPods 1.4.0 或更高版本。
*   在 Xcode 中打开您的项目。
*   您的项目必须适用于 iOS 8 或更高版本。
*   Swift 项目必须使用 Swift 3.0 或更高版本。
*   设置用于运行您的应用的一台 iOS 真机设备或 iOS 模拟器。
*   为了支持云消息传递,您需要:
    *   一台 iOS 真机设备
    *   一个 [Apple 开发者帐号](https://www.google.com/url?sa=D&q=https%3A%2F%2Fdeveloper.apple.com%2Faccount)所对应的 Apple 推送通知身份验证密钥(即APNs Auth Key(APNs key ID和Team ID),也可以使用APNs推送证书的.p12文件)
*   在 Xcode 中通过 App > Capabilities 启用推送通知功能。
*   对于所有其他 Firebase 产品,您可以使用 iOS 真机设备或 iOS 模拟器。
*   使用您的 Google 帐号[登录 Firebase](https://console.firebase.google.com/)。
第 1 步:创建 Firebase 项目

您必须先创建一个 Firebase 项目,并将其关联到您的 iOS 应用,然后才能将 Firebase 添加到您的 iOS 应用。访问了解 Firebase 项目以详细了解相关信息。
创建 Firebase 项目

image.png

image.png
第 2 步:在 Firebase 中注册您的应用

有了 Firebase 项目后,在项目中添加自己的iOS应用

  1. Firebase 控制台的项目概览页面的中心位置,点击 iOS 图标以启动设置工作流。
    如果您已向 Firebase 项目添加了应用,请点击添加应用以显示平台选项。
  2. 在 iOS 软件包 ID 字段中输入应用的软件包 ID
    确保输入应用实际使用的 ID。
  • 在 XCode 中打开您的应用,然后在顶级 Runner 目录中访问常规标签,找到此软件包 ID。软件包标识符字段的值是 iOS 软件包 ID(例如 com.yourcompany.yourproject)。
    注意:bundle ID是唯一的。在向 Firebase 项目注册应用后,将无法添加或修改此值。
  1. (可选)根据设置工作流的提示输入其他应用信息。
  1. 点击注册应用。
第 3 步:添加 Firebase 配置文件
  1. 点击下载 GoogleService-Info.plist 以获取您的 Firebase iOS 配置文件 (GoogleService-Info.plist)。
    • 此文件支持重复下载 Firebase iOS 配置文件
    • 此文件名称必须是“GoogleService-Info.plist”不可更改。
  2. 将配置文件移至 Xcode 项目的根目录中。如果出现提示,请选择将配置文件添加到所有目标。
    如果您的项目中有多个软件包 ID,则必须将每个软件包 ID 与 Firebase 控制台中的注册应用相关联,使每个应用都有自己的 GoogleService-Info.plist 文件。
注意:该 Firebase 配置文件包含项目的唯一、非机密标识符。
第 4 步:将 Firebase SDK 添加到您的应用
  1. 如果您没有 Podfile,请创建一个: cd your-project-directory pod init
  2. 将想要用在应用中的 pod 添加到 Podfile。例如,对于 Analytics: pod 'Firebase/Analytics' 此 pod 会在您的 iOS 应用中添加 Firebase 正常运行所需的必备库以及 Google Analytics for Firebase 功能。
  3. 安装 pod,然后打开 .xcworkspace文件以便在 Xcode 中查看该项目:
pod install
open your-project.xcworkspace
第 5 步:在应用中初始化 Firebase

添加初始化代码。

  1. 在 UIApplicationDelegate中导入 Firebase 模块并签订代理:
@import Firebase;

签订代理<FIRMessagingDelegate>

如:


image.png
  1. 配置一个 FirebaseApp 共享实例(通常在应用的 application:didFinishLaunchingWithOptions:方法中配置):
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
  
  
    [FIRApp configure];
    [FIRMessaging messaging].delegate = self;
    
    //注册远程通知。这显示了第一次运行时的权限对话框to
    //在更合适的时间显示对话框,相应移动此注册。
    if (@available(iOS 10.0, *)) {
        if ([UNUserNotificationCenter class] != nil) {
            // iOS 10 or later
            // For iOS 10 display notification (sent via APNS)
            [UNUserNotificationCenter currentNotificationCenter].delegate = self;
            UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert |
            UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
            [[UNUserNotificationCenter currentNotificationCenter]
             requestAuthorizationWithOptions:authOptions
             completionHandler:^(BOOL granted, NSError * _Nullable error) {
                 // ...
             }];
        } else {
            // iOS 10 notifications aren't available; fall back to iOS 8-9 notifications.
            UIUserNotificationType allNotificationTypes =
            (UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge);
            UIUserNotificationSettings *settings =
            [UIUserNotificationSettings settingsForTypes:allNotificationTypes categories:nil];
            [application registerUserNotificationSettings:settings];
        }
    } else {
        // Fallback on earlier versions
    }
    
    [application registerForRemoteNotifications];
    NSDictionary *notificationPayload = launchOptions[UIApplicationLaunchOptionsRemoteNotificationKey];
    
    [self initRootVC];
    return YES;
}

代理方法实现

// [START receive_message]
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    //如果你在后台接收到一条通知消息,
    //    这个回调将不会被触发,直到用户点击通知启动应用程序。
    // TODO:处理通知数据
    
    //当swizzling被禁用时,你必须让消息传递知道消息,以便进行分析
    // [FIRMessaging消息]appdid应收款emessage:userInfo];
    
    //打印消息ID。
    if (userInfo[kGCMMessageIDKey]) {
        NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]);
    }
    
    // Print full message.
    NSLog(@"%@", userInfo);
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    //如果你在后台接收到一条通知消息,
    //    这个回调将不会被触发,直到用户点击通知启动应用程序。
    // TODO:处理通知数据
    
    //当swizzling被禁用时,你必须让消息传递知道消息,以便进行分析
    // [FIRMessaging消息]appdid应收款emessage:userInfo];
    
    //打印消息ID。
    if (userInfo[kGCMMessageIDKey]) {
        NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]);
    }
    
    // Print full message.
    NSLog(@"%@", userInfo);
    
    completionHandler(UIBackgroundFetchResultNewData);
}
// [END receive_message]

// [START ios_10_message_handling]
//接收iOS 10设备的显示通知。
//当app在前台时处理传入的通知消息。
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
       willPresentNotification:(UNNotification *)notification
         withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
    NSDictionary *userInfo = notification.request.content.userInfo;
    
    //当swizzling被禁用时,你必须让消息传递知道消息,以便进行分析
    // [FIRMessaging消息]appdid应收款emessage:userInfo];
    
    //打印消息ID。
    if (userInfo[kGCMMessageIDKey]) {
        NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]);
    }
    
    // Print full message.
    NSLog(@"%@", userInfo);
    
    //将此更改为您首选的显示选项
    if (@available(iOS 10.0, *)) {
        completionHandler(UNNotificationPresentationOptionNone);
    } else {
        // Fallback on earlier versions
    }
}

//后台运行: 指的是程序已经打开, 用户看不见程序的界面, 如锁屏和按Home键.
//程序退出: 指的是程序没有运行, 或者通过双击Home键,关闭了程序.**
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
         withCompletionHandler:(void(^)(void))completionHandler  API_AVAILABLE(ios(10.0)){
    NSDictionary *userInfo = response.notification.request.content.userInfo;
    if (userInfo[kGCMMessageIDKey]) {
        NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]);
    }
    
    // Print full message.
    NSLog(@"%@", userInfo);
    
    completionHandler();
}

// [END ios_10_message_handling]

// [START refresh_token]
- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken {
    NSLog(@"FCM registration token: %@", fcmToken);
    // Notify about received token.
    NSDictionary *dataDict = [NSDictionary dictionaryWithObject:fcmToken forKey:@"token"];
    [[NSNotificationCenter defaultCenter] postNotificationName:
     @"FCMToken" object:nil userInfo:dataDict];
    // TODO:如果需要,发送令牌到应用服务器。
    //注意:这个回调在每次应用程序启动时以及每次生成新令牌时触发。
}
// [END refresh_token]

// [START ios_10_data_message]
//当应用程序在前台时,直接从FCM(绕过APNs)接收iOS 10+上的数据消息。
//要启用直接数据消息,可以设置[消息传递消息传递]。shouldEstablishDirectChannel是的。
- (void)messaging:(FIRMessaging *)messaging didReceiveMessage:(FIRMessagingRemoteMessage *)remoteMessage {
    NSLog(@"Received data message: %@", remoteMessage.appData);
}
// [END ios_10_data_message]

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
    NSLog(@"Unable to register for remote notifications: %@", error);
}

//在这里添加这个函数只是为了调试,如果启用了swizzling,则可以删除它。
//如果swizzling被禁用,那么必须实现这个函数,以便APNs设备令牌可以被配对
// FCM注册令牌。
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    NSLog(@"APNs device token retrieved: %@", deviceToken);
    //将来需要将此Token上传给后台服务器
    //禁用swizzling后,必须在这里设置APNs设备令牌。
    // (FIRMessaging消息)。APNSToken = deviceToken;
}

添加初始化代码后,运行您的应用以便向 Firebase 控制台发送验证信息,证明您已成功安装 Firebase。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,905评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,140评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,791评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,483评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,476评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,516评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,905评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,560评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,778评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,557评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,635评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,338评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,925评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,898评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,142评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,818评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,347评论 2 342

推荐阅读更多精彩内容