app推送研究

3,472 阅读9分钟

以下包含firebase推送的介绍和配置,国内各个推送的对比。

firebase messaging

前言

推送服务在国内有很多服务商,但是如果是做海外 App ,推荐还是使用 Google 自己的推送服务,毕竟海外常用的手机型号,都是有 Google 服务在的。

Google 的推送服务,以前叫做 GCM(Google Cloud Message)。而自从 Google 将 Firebase 收购之后,就将推送服务并到 Firebase 的一项服务中了,现在叫做 FCM。

介绍

Firebase 原本是一家实时后端数据库的创业公司,主要用于帮开发者快速的写出 Web 端和移动端的应用,类似于国内 Bmob 这种后端云服务,让前端或者客户端开发者,一行服务端代码都不用写,只需要简单的配置,就可以快速的开发出一款引用来(当然也支持服务端sdk,和app后端集成开发)。

之后 Firebase 被 Google 收购,开始使用 Google 的云服务,又增加了一些 Google 本身的服务,更丰富了它的功能。

Firebase 除了支持 Android 之外,也支持其他的一些语言和平台,例如:iOS、C++、Unity。

基本上你能想到的功能,Firebase 都是支持的,主要我觉得比较好用的功能:授权登录、推送、实时数据库、CDN存储、崩溃报告、事件统计、带回源的动态邀请、广告、推广等。

所以如果你需要开发一款在海外使用的 App 的话,Firebase 是一个不错的选择,Firebase 采用的是模块化集成,使用到什么功能,就集成什么功能即可。

firebase messaging官方文档及介绍

firebase.google.com/docs/cloud-…

推送firebase 客户端界面

基本原理

FCM消息服务器是通过一个叫注册令牌的字符串来定位设备的,APP初次启动时,FCM SDK会为客户端应用生成一个注册令牌,客户端应用需要获取到这个注册令牌并发送到APP服务器并和当前APP用户关联保存,当APP服务器需要向指定用户发送通知消息,需要检索到与用户关联保存的注册令牌,通过这个注册令牌向FCM消息服务器发送通知消息,FCM消息服务器通过这个注册令牌,定位移动设备,并发送通知消息。

注册令牌在以下几种情况会有变更:

  • 通过FirebaseInstanceId.getInstance().deleteToken()主动删除注册令牌
  • 用户卸载重装APP
  • 用户清除应用数据
  • 应用在新设备上恢复

检查Google Play Services可用性的方法

if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) != ConnectionResult.SUCCESS) {
            Log.e(TAG, "Google Play service is not available");
            // GoogleApiAvailability.getInstance().makeGooglePlayServicesAvailable(this);
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("Download Google Play Service")
                    .setMessage("Google Play Service is required for the app.")
                    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            Intent intent = new Intent(Intent.ACTION_VIEW);
                            intent.setData(Uri.parse("market://details?id=com.google.android.gms"));
                            if (intent.resolveActivity(getPackageManager()) == null) {
                                intent.setData(Uri.parse(
                                        "https://play.google.com/store/apps/details?id=com.google.android.gms"));
                                // intent.setPackage("com.android.vending");
                            }
                            startActivity(intent);
                        }
                    })
                    .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            Toast.makeText(MainActivity.this, "Google Play Services is required.", Toast.LENGTH_LONG).show();
                        }
                    });
            builder.show();
        }

网络

好像不fq也可以接收消息

配置

andorid
  1. firebase注册应用

  2. 下载配置文件google-services.json, 放到app文件夹下

  3. 添加firebase sdk

    项目级 build.gradle(<项目>/build.gradle):

    buildscript {
      repositories {
        // Check that you have the following line (if not, add it):
        google()  // Google's Maven repository
      }
      dependencies {
        ...
        // Add this line
        classpath 'com.google.gms:google-services:4.3.3'
      }
    }
    
    allprojects {
      ...
      repositories {
        // Check that you have the following line (if not, add it):
        google()  // Google's Maven repository
        ...
      }
    }
    

    应用级 build.gradle(<项目>/<应用模块>/build.gradle):

      apply plugin: 'com.android.application'
      apply plugin: 'com.google.gms.google-services'

      dependencies {
        implementation 'androidx.legacy:legacy-support-v4:1.0.0'
        implementation 'com.google.firebase:firebase-core:17.0.0'
        implementation 'com.google.firebase:firebase-analytics:17.2.1'
        implementation 'com.google.firebase:firebase-messaging:20.0.0'
      }
  1. 修改android manifest文件, application节点下
  <service
      android:name="java.MyFirebaseMessagingService"
      android:exported="false">
      <intent-filter>
          <action android:name="com.google.firebase.MESSAGING_EVENT" />
      </intent-filter>
  </service>
  1. 添加firebase messageing服务
  import android.util.Log;
  import com.google.firebase.messaging.FirebaseMessagingService;

  public class MyFirebaseMessagingService extends FirebaseMessagingService {

      private static final String TAG = "MyFirebaseMsgService";

      /**
       * Called if InstanceID token is updated. This may occur if the security of
       * the previous token had been compromised. Note that this is called when the InstanceID token
       * is initially generated so this is where you would retrieve the token.
       */
      @Override
      public void onNewToken(String token) {
          Log.d(TAG, "Refreshed token: " + token);

          // If you want to send messages to this application instance or
          // manage this apps subscriptions on the server side, send the
          // Instance ID token to your app server.
          // sendRegistrationToServer(token);
      }
  }

  1. 获取app当前token

    // MainActivity onCreate方法
    FirebaseInstanceId.getInstance().getInstanceId()
                    .addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
                        @Override
                        public void onComplete(@NonNull Task<InstanceIdResult> task) {
                            if (!task.isSuccessful()) {
                                Log.w(TAG, "getInstanceId failed", task.getException());
                                return;
                            }
    
                            // Get new Instance ID token
                            String token = task.getResult().getToken();
    
                            // Log and toast
                            String msg = token;
                            Log.d(TAG, ">>>>>>>>>>token" + msg);
                            // Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
                        }
                    });
    
  2. 配置图标

         <!-- [START fcm_default_icon] -->
            <!-- Set custom default icon. This is used when no icon is set for incoming notification messages.
                 See README(https://goo.gl/l4GJaQ) for more. -->
            <meta-data
                android:name="com.google.firebase.messaging.default_notification_icon"
                android:resource="@drawable/ic_stat_ic_notification" />
    

    issue

    Program type already present: android.support.v4.media.MediaBrowserCompat$ConnectionCallback$ConnectionCallbackInternal

    解决方案:android studio工具栏-refactor-migrate to androidX

Ios
  1. firebase注册应用

  2. 苹果开发者中心Certificates, Identifiers & Profiles,推荐2)

    1)

    • identifers-进入指定应用,Capabilities勾选push notification
    • 添加push证书
    • 打开mac应用-秘钥串访问中心-证书助理-从指定机构颁发证书-下载csr文件
    • 回到开发者中心-上传csr文件-下载cer文件,双击安装
    • 秘钥串访问中心-展开指定cer文件-右键到出p12证书
    • firebase项目ios 应用配置上传p12证书

    2)

    • identifers-进入指定应用,Capabilities勾选push notification,记录Team ID
    • keys-选择apns添加key并下载p8密钥文件,记录key id
    • firebase项目ios 应用配置上传p8密钥,并输入team ID和key id
  3. 下载配置文件GoogleService-Info.plist,文件移至 Xcode 项目的根目录并将其添加至所有目标。

  4. 添加firebase sdk:Podfile添加依赖,并pod install --verbose --no-repo-update

    pod 'Firebase/Analytics'
    pod 'Firebase/Messaging'
    
  5. 添加初始化代码

    AppDelegate类didFinishLaunchingWithOptions方法;

    #import "AppDelegate.h"
    #import "MainViewController.h"
    #import "FIRApp.h"
    
    @implementation AppDelegate
    
    - (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
    {
        [FIRApp configure];
        [FIRMessaging messaging].delegate = self;
        // 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) {
              // ...
            }];
        [application registerForRemoteNotifications];
    
    
        self.viewController = [[MainViewController alloc] init];
        return [super application:application didFinishLaunchingWithOptions:launchOptions];
    }
    

    issue: pods依赖问题

    在build setting 里面设置下:target--> build setting-->User Header Search Paths点击加号$(PODS_ROOT) (注意、这块是没有引号的哟)同时、将后面的 nun-recursive改为recursive

  6. xcode signing & capabilities

    点击+号添加push notifications

[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0]; //清除角标

需求

android系统状态栏图标,100*100png,logo主体灰色和白色各一个,背景透明

firebase客户端使用介绍

  1. 访问https://console.firebase.google.com/project/projectName/notification,需要访问权限;

  2. 进入cloud Messaging页面后,点击new notification;

  3. 进入消息配置页面后,按需分配即可;

    Step1: Notification title, Notification text 必填(ios不支持图片);

    Step2: 选中推送的app,分android和ios平台,一般两个都选中即可;

    Step3: 选择发送时间,支持即时发送,定时发送,轮循发送,以及一些自定义规则,支持时区选择;

    Step4: 选择发送对象的条件,是从appstore订阅的或者第一次打开之类的,我们app可以不选择;

    Step5: 选择这个通知到达系统时一些配置。比如: Sound 是否需要声音提示;iOS badge 是否需要在ios桌面app的显示角标值以及角标值,一般配置1即可;其他默认选中或者不填即可;

    Step6: 最后点击review 并publish即可;

角色管理
  1. 管理员访问https://console.firebase.google.com/project/projectName/settings/iam
  2. 进入项目设置Users and permissions 页面,点击add member
  3. 输入邀请对象邮箱,选择角色,角色一般选择editor即可;
注意点
  1. ios基本不可以定制推送格式,只支持文本和emoji;android支持图文混排,图片是在线链接形式;
  2. 一般推送是app在后台时(未使用时)向系统推送的通知,通知常驻在系统通知栏,可以通过点击通知打开app,或者滑动移除通知;如果app在前台(正在使用),推送可以做到显示但是有展示的时间限制,不像在后台时那样常驻在系统通知栏,这块可能需要继续研究;
官方文档及介绍

firebase.google.com/docs/cloud-…

推送对比

firebase messaging

谷歌推送服务,firebase.google.com/?authuser=0 适合国外

优点:

		跨平台服务集成(谷歌fcm和苹果ans);

		有客户端UI推送界面;

		客户端只原生平台,web端和unity(有第三方Cordova插件);

		服务端支持多种主流开发语言;

缺点:

		android需要google服务框架;	

待研究:

		fcm国内不稳定(有谷歌服务框架的情况下,可能是谷歌服务器在国内问题)??

极光推送

国内优秀的推送服务,国内第三方最早,专注推送,github.com/jpush/jpush…

优点:

		跨平台服务集成(极光服务和苹果ans。安卓的厂商服务限vip);

		有客户端UI推送界面;

		客户端支持原生平台,web端和**cordova**等平台sdk或插件,http://docs.jiguang.cn/jpush/client/client_plugins/

		服务端支持多种主流开发语言

缺点:

		谷歌fcm、国内厂商系统级别推送是**收费**的,https://community.jiguang.cn/article/280121,https://www.jiguang.cn/push-price

		免费推送频率、速度受限;

待研究:

		有cordova插件(暂未深入研究过可行性);

微软azure推送

azure.microsoft.com/en-us/servi… 适合国外

优点:

		跨平台服务集成(苹果ans、谷歌fcm、百度云);

		有客户端UI推送界面,但是界面一般;

		服务端支持多种主流开发语言;

缺点:

		android基本需要google服务框架;

		配置繁琐,总体看起来基于firebase服务;

		客户端只支持原生平台sdk;

微软appcenter推送

有cordova插件和其他平台sdk,但是即将停止服务。。

友盟推送

国内优秀的推送服务https://www.umeng.com/push 适合国内

优点:

		跨平台服务集成(友盟服务和苹果ans,**国内五大厂商服务免费**);

		有客户端UI推送界面;

缺点:

		不支持谷歌fcm服务

		客户端除了原生平台(android和ios),没有其他平台sdk;

		服务端sdk支持java、python、PHP;

		免费推送频率、速度受限;

个推推送

国内最早的一批推送服务,www.getui.com/push 收费和服务支持基本和极光差不多

优点:

		跨平台服务集成(个推服务和苹果ans,国内厂商服务限vip);

		有客户端UI推送界面;

		客户端支持原生平台,web端和**cordova**等平台sdk或插件,http://docs.getui.com/getui/more/plugin/

		服务端支持多种主流开发语言;

缺点:

		谷歌fcm、国内厂商系统级别推送是**收费**的;

		免费推送频率、速度受限;

待研究:

		有cordova插件(暂未深入研究过可行性);

总结

国内第三方推送

市场占有率:

		极光>个推>友盟=Moboush=腾讯信鸽>百度>云巴推送

价格:

		Mobpush>云巴>腾讯信鸽=友盟=百度>极光&个推