创建Firebase项目并接入Firebase推送: Firebase Cloud Messaging (FCM)

news/2024/7/20 22:21:01 标签: android, ios, android studio

1.FCM简介:

Firebase Cloud Messaging (FCM) 是一种跨平台消息传递解决方案,可供您可靠地传递消息,而且还是免费的服务。支持 Android,IOS,Web,Flutter,Unity.

消息类型

可以使用 FCM 向客户端发送两种类型的消息:

  • 通知消息,有时被称为“显示消息”。此类消息由 FCM SDK 自动处理。

  • 数据消息,由客户端应用处理。

通知消息包含一组用户可见的预定义键。与其相对,数据消息只包含用户定义的自定义键值对。通知消息可以包含可选的数据载荷。两种消息类型的载荷上限均为 4000 个字节,但从 Firebase 控制台发送消息时会强制执行 1024 个字符的限制。

使用情景

如何发送

通知消息

当客户端应用在后台运行时,FCM SDK 会代表客户端应用向最终用户设备显示消息。如果应用在收到通知时正在前台运行,应用的代码会决定行为。通知消息包含一组预定义的用户可见的键和一个由自定义键值对组成的可选的数据载荷。

  1. 在可信环境(例如 Cloud Functions 或应用服务器)中,使用 Admin SDK 或者 FCM 服务器协议:设置 notification 键。可能包含可选的数据载荷。 一律可折叠。

请参阅一些显示通知示例并发送请求载荷。

  1. 使用 Notifications Composer:输入消息文本、标题等,然后发送。通过提供自定义数据添加可选的数据载荷。

数据消息

客户端应用负责处理数据消息。数据消息仅包含自定义键值对,没有保留键名(请参阅下文)。

在可信环境(例如 Cloud Functions 或应用服务器中),使用 Admin SDK 或者 FCM 服务器协议:仅设置 data 键。

通知消息

如果要进行测试,或者要开展营销、重新吸引用户,可以使用 Firebase 控制台发送通知消息。Firebase 控制台提供基于分析的 A/B 测试,可帮助优化和改进营销消息。

如需使用 Admin SDK 或 FCM 协议以编程方式发送通知消息,可使用通知消息中用户可见部分所必需的预定义键值对选项集来设置 notification 键。例如,以下是即时通讯应用中的 JSON 格式的通知消息。用户可能会在设备上看到标题为“Portugal vs. Denmark”、文本为“great match!”的消息:

{
  "message":{
    "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
    "notification":{
      "title":"Portugal vs. Denmark",
      "body":"great match!"
    }
  }
}

应用在后台运行时,通知消息将被传递至通知面板。应用在前台运行时,消息由回调函数处理。

数据消息

使用自定义键值对设置适当的键,以将数据载荷发送至客户端应用。

请确保未在自定义键值对中使用任何保留字词。保留字词包括“from”“notification”“message_type”或以“google”或“gcm”开头的任何字词。

例如,下方所示为上述同一即时通讯应用中的一条 JSON 格式的消息,在此消息中,信息封装在常用的 data 键中,且客户端应用需要解读相应内容:

{
  "message":{
    "token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
    "data":{
      "Nick" : "Mario",
      "body" : "great match!",
      "Room" : "PortugalVSDenmark"
    }
  }
}

2.FCM 架构概览:

通过上图架构可以看到可以发送FCM的平台:

1:开发中常用的:项目服务端server端接入Firebase Admin SDK

2.客户端可以直接发送FCM

3.通过Firebase 操作台发送FCM

3.生命周期流:

  • 注册设备以接收来自 FCM 的消息。客户端应用的实例注册以接收消息,并获取唯一标识应用实例的注册令牌。

  • 发送和接收下行消息

  • 发送消息。应用服务器向客户端应用发送消息:

  1. 消息会在 Notifications Composer 或受信任的环境中编写,并且消息请求会被发送到 FCM 后端。

  1. FCM 后端接收消息请求,生成消息 ID 和其他元数据,并将其发送到平台特定的传输层。

  1. 当设备在线时,系统会通过平台特定的传输层将消息发送到设备。

  1. 在设备上,客户端应用会接收到消息或通知。

4.客户端接入:

第 1 步:创建 Firebase 项目

需要先创建一个要关联到 Android 应用的 Firebase 项目,然后才能将 Firebase 添加到 Android 应用。请访问了解 Firebase 项目以了解详情。

创建项目:https://console.firebase.google.com/?hl=zh-cn

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

如需在 Android 应用中使用 Firebase,需要向 Firebase 项目注册的应用。注册应用的过程通常称为将应用“添加”到项目中。

第 3 步:添加 Firebase 配置文件

  1. 下载 Firebase Android 配置文件 (google-services.json),然后将其添加到应用中:

  1. 点击下载 google-services.json 以获取 Firebase Android 配置文件。

  1. 将配置文件移到应用的模块(应用级)根目录中。

google-server.json:

{
  "project_info": {
    "project_number": "200570714500",
    "project_id": "testproject-82da6",
    "storage_bucket": "testproject-82da6.appspot.com"
  },
  "client": [
    {
      "client_info": {
        "mobilesdk_app_id": "1:200570714500:android:31bd6c1683be9fb6a485d1",
        "android_client_info": {
          "package_name": "com.test.project.android"
        }
      },
      "oauth_client": [
        {
          "client_id": "200570714500-g7s70nmqogiviequmsegmuo49kf8knnb.apps.googleusercontent.com",
          "client_type": 1,
          "android_info": {
            "package_name": "com.test.project.android",
            "certificate_hash": "b0bd34f3447d5d63bf620ae01a5bb494759ee845"
          }
        },
        {
          "client_id": "200570714500-b9i97kadm6me2b2hb9e7l3cmsop63ajk.apps.googleusercontent.com",
          "client_type": 3
        }
      ],
      "api_key": [
        {
          "current_key": "AIzaSyBys0WVyFocO8ulfPdqIWMKCPWvy1HlppY"
        }
      ],
      "services": {
        "appinvite_service": {
          "other_platform_oauth_client": [
            {
              "client_id": "200570714500-b9i97kadm6me2b2hb9e7l3cmsop63ajk.apps.googleusercontent.com",
              "client_type": 3
            }
          ]
        }
      }
    }
  ],
  "configuration_version": "1"
}

放到项目中的位置:放到项目的./app 目录下即可,如果要区分debug or release 那就可以根据多渠道创建对应的文件夹下:

第 4 步:将 Firebase SDK 添加到应用中

buildscript {

    repositories {
      // Make sure that you have the following two repositories
      google()  // Google's Maven repository
      mavenCentral()  // Maven Central repository
    }

    dependencies {
      ...

      // Add the dependency for the Google services Gradle plugin
      classpath 'com.google.gms:google-services:4.3.15'
    }
}

allprojects {
  ...

  repositories {
    // Make sure that you have the following two repositories
    google()  // Google's Maven repository
    mavenCentral()  // Maven Central repository
  }
}
dependencies {
  implementation platform('com.google.firebase:firebase-bom:31.2.0')
  implementation 'com.google.firebase:firebase-analytics'
  implementation 'com.google.firebase:firebase-auth'
  implementation 'com.google.firebase:firebase-firestore'
 implementation  'com.google.firebase:firebase-messaging'
}
plugins {
    id 'com.android.application'

    // Add the Google services Gradle plugin
    id 'com.google.gms.google-services'
    ...
}

到此已经将Firebase sdk 引入到项目中了

5. FCM项目中使用:

5.1 首先创建一个类继承FirebaseMessagingService ,实现onMessageReceived()和 onNewToken()方法

class MessagingService : FirebaseMessagingService(), LifecycleObserver {

    /**
     * Called when message is received.
     *
     * @param remoteMessage Object representing the message received from Firebase Cloud Messaging.
     */
    override fun onMessageReceived(remoteMessage: RemoteMessage) {
        if (remoteMessage == null) {
            return
        }
        val remoteMessageMap: Map<String, String> = remoteMessage.data;
        if (remoteMessageMap == null || remoteMessageMap.isEmpty()) {
            return
        }
        val json = JSON.toJSON(remoteMessageMap) as JSONObject
    }

    override fun onNewToken(token: String) {
        try {
            MyApplication.instance?.let {
                ApiClient.getApiService(it.sessionManager).postPushToken(PushTokenBody(token))
            }
            val param = HashMap<String, Any>()
            param.put("fcm_registration_token", token)
            AppLog.setHeaderInfo(param)
        } catch (e: java.lang.Exception) {

        }
    }
}

onMessageReceived()是监听推送的消息,onNewToken()是当有新的Firebase token 时的回调,有新的 token 及时上传server

由于FirebaseMessagingService 是一个 service 所以要在AndroidManifest中声明:

        <service
            android:name=".ui.notification.MessagingService"
            android:exported="false">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT" />
            </intent-filter>
        </service>

5.2 启动APP时 获取firebase fcm token 上传server

初次启动APP时,FCM SDK 会为客户端应用实例生成一个注册令牌 (registration token),注意上面睡到 FirebaseMessagingService 并重写 onNewToken 来获取更新此token。

fcm token 可能会在发生下列情况时更改:

  • 应用在新设备上恢复

  • 用户卸载/重新安装应用

  • 用户清除应用数据。

获取fcm token:

FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
    if (!task.isSuccessful) {
        Log.w(TAG, "Fetching FCM registration token failed", task.exception)
        return@OnCompleteListener
    }

    // Get new FCM registration token
    val token = task.result

    // Log and toast
    val msg = getString(R.string.msg_token_fmt, token)
    Log.d(TAG, msg)
    Toast.makeText(baseContext, msg, Toast.LENGTH_SHORT).show()
})
FirebaseMessaging.getInstance().getToken()
    .addOnCompleteListener(new OnCompleteListener<String>() {
        @Override
        public void onComplete(@NonNull Task<String> task) {
          if (!task.isSuccessful()) {
            Log.w(TAG, "Fetching FCM registration token failed", task.getException());
            return;
          }

          // Get new FCM registration token
          String token = task.getResult();

          // Log and toast
          String msg = getString(R.string.msg_token_fmt, token);
          Log.d(TAG, msg);
          Toast.makeText(MainActivity.this, msg, Toast.LENGTH_SHORT).show();
        }
    });

6.使用 Firebase 控制台发送消息进行测试

可以使用 Firebase 控制台中的 Notifications Composer 发送通知消息。尽管使用这种方法发送消息的灵活性或可伸缩性不及使用 Admin SDK 或 HTTP 和 XMPP 协议,但它非常适合用于测试或者针对性较强的营销活动及用户互动。Firebase 控制台提供基于分析结果的 A/B Testing 测试,可帮助优化和改进营销消息。

从 Notifications Composer 发送通知消息时,Google 以如下方式使用您在表单字段中输入的值:

  • 用户细分有效期等字段用于确定消息目标和传送选项。

  • 通知文字自定义数据等字段以由键值对构成的载荷形式发送至客户端。

这些字段会映射至使用 Message 对象时可用的键。例如,在编辑器的自定义数据字段中输入的键值对是作为通知的 data 载荷处理的。其他字段直接映射至 notification 对象或平台专用通知配置中的键。

请注意,Notifications Composer 中的某些字段在使用 FCM API 时不可用。例如,您可以根据应用版本、语言、浏览器类型、浏览器版本或用户属性来定位细分用户群,而这些方法均无法通过服务器 API 来使用。

Firebase 控制台向客户端发送的键有:

控制台字段标签

说明

notification.title

通知标题

指示通知标题。

notification.body

通知文字

指示通知正文。

data

自定义数据

您定义的键值对。它们以数据载荷的形式传送至应用以进行处理。

决定消息传送方式的键包括:

控制台字段标签

说明

sound

声音

指示设备收到通知时要播放的声音。

time_to_live

有效期

此参数指定设备离线后消息在 FCM 存储区中保留的时长(以秒为单位)。 如需了解详情,请参阅设置消息的有效期。

这样通过控制台发送的消息推送,APP的onMessageReceived()就能接收到该消息

这个时候当APP杀死或者切后台时,FCM SDK会直接走系统的notificaion.如果这个时候APP在activity status 收到push message 后就可以做独立的逻辑了

7.使用 Firebase Admin SDK for FCM发送消息

Admin FCM API 可处理后端身份验证工作,同时便于发送消息和管理主题订阅。使用 Firebase Admin SDK,可以执行以下操作:

  • 向单个设备发送消息

  • 向主题和与一个或多个主题匹配的条件语句发送消息。

  • 为设备订阅和退订主题

  • 针对不同目标平台构建量身定制的消息载荷。

Admin Node.js SDK 提供了用于向设备组发送消息的方法。

使用Firebase Admin SDK 需要从Firebase 控制台获取json:

控制台->设置-->项目设置-->服务账号-->生成新的秘钥

拿到的admin sdk json 样式:

{
  "type": "service_account",
  "project_id": "testproject-82da6",
  "private_key_id": "2dab734ab58df4f1b0898cde1e8c8b488ae3134d",
  "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCy3HNgzSSUTG8r\ny7CulZZr7CdW70UEfL6dbla1b9lmxdIDWmMz+/8tux8dSr7FKjvUhHjqF5R8Ua7b\nCySuvvwjhwHm9u9kC1bOmlOhzMMsfRCQqIFU5nPvq+6KIrELwrIk6wpwXof4+6ns\nUhPrOv3AyEi1+yeTlXipexsaQ1X45qPfCvAJea59DpbnObhtX0g5K5tp6IqwaXwg\ncXoUgTeQlkjG3f3Y5A/wNH2etAqzA299ixUyl/20hHyOY8wtTNj67ZgsW4bvufXF\n8+y2vm4i2eIgV1uvHpPRBHcH5lV8PJH8Pgd3n9dXDSuKDaq/zc87DbPC9ybSovLA\nkTnzUZWDAgMBAAECggEAVhz/S87Y2rGGIL7b3OJWXrV/J0LhpsxsdZ2HD6m/MNTz\nTPv6oS+lZx4dV9wBxymTTrlNAd/CdKxbFEjkK2H2QSCiENI45aDz9VqmA1NzcHry\nO8N1KSwfC3hqy4TyWqgtXsru5rUMoBqCcC4AOxPW0jdbkopOPqcLRgXoQZfDz6Zk\nhK2QhaIVbw2sHZZsCNYagRI+7AlS6VDT9FnREj5HoeyNFiNCT6th7Am6mi040mI1\nJaAJ2OhvNyW4vQpaLjT8Dadgw4uU3yLt+0wKtQJU83qNtgyiXnCNp4En7c+d/f0A\nrovZVpvA5LpVzokq+9nNTtrVEB1BmuxAyZnV/6I+eQKBgQDtCX791LezaSHAuIgL\nTlwQjCnd4nz+X2kYAACdfJMRHVuV2JcyHrV0Z+ICMX/hlqlyO9sP0Rs4gAfBtX2a\nerWzjT0OfhhJaTULY7nO/sXBNpsb/4LM4Ac6WN+gqL20Qp7ekExs5/cUoWjhsEQK\no+tauuMvAhGSG/Kz1ALa+5DmtQKBgQDBK4POi9+w9h+/FvlzKl6/1RSg1HAf3DyO\nsih+1dcb/YkptFH460tns3zq9AZBX3DAQPjb0yL8uEfdRBVtnCwEASVbujgKYZz+\ntsBkR6ZsPrBVsFP5bwvT6k7ioZgoQiriNwQkxrUa4Z9NdD/bWB6liEUp1f86vD03\noZ/bw2U2VwKBgCTvad5bmxRVuXCyUGCSoT3i2VM9y4RHkbSvq2je1HvCO1cqHMUu\ni8/LsCfvVqHsPBMUyJm6V6eCK7M/eIbtwApuY6kydM5bmmxf6cAbau0keR7vvY33\nCqlI1+/M22KPTvoXOhFuQ83vKMyiDrgpuq60mFnm1J4TxMnIq3k74eRRAoGBAKeH\nm8qYWKpa6vGJdVJCHuZ0YG2TkKKxGPwQ2zoVL3ghDMJUlvsw5bbMXbxPYtVzdo/m\nSW4s0R0onXryvzrOxQW8ELBa8pteSRBHYtgVo+og/EF0qX+cpT9m6H948kOIDzUd\nzcQvaYYkw0ojVfZfmESryIAeDjrcYqNK0x9/eNoFAoGBAJZ8+h0Fi0bonctG7TwC\nR0rRX04l1VeOnMLhlgXZp5z4lzl7Bpuuua2yJHRnuJyN46hUxv8aNNKYeQbv8tTD\nGbCxJnSmL636aYwPIBYylU74CjIoUmcC2ce7MoT7c9zXaZvEmhSWEyzHTDXTJwL4\nhbAsd2wwEC0PJuU/Ri3rfk+X\n-----END PRIVATE KEY-----\n",
  "client_email": "firebase-adminsdk-62mnh@testproject-82da6.iam.gserviceaccount.com",
  "client_id": "114249923120443166527",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-62mnh%40testproject-82da6.iam.gserviceaccount.com"
}

admin sdk 发送FCM message:

private static String getAccessToken() throws IOException {
  GoogleCredentials googleCredentials = GoogleCredentials
          .fromStream(new FileInputStream("service-account.json"))
          .createScoped(Arrays.asList(SCOPES));
  googleCredentials.refreshAccessToken();
  return googleCredentials.getAccessToken().getTokenValue();
}

这种方式客户端也是可以收到FCM Message 的

--至:大新


http://www.niftyadmin.cn/n/111580.html

相关文章

参考 Promise/A+ 规范和测试用例手写 Promise

前言 这可能是手写promise较清晰的文章之一。 由浅至深逐步分析了原生测试用例&#xff0c;以及相关Promise/A规范。阅读上推荐以疑问章节为切入重点&#xff0c;对比Promise/A规范与ECMAScript规范的内在区别与联系&#xff0c;确定怎样构建异步任务和创建promise实例。然后开…

新增2000w播放、单月涨粉80w!13秒短视频竟成B站热门

知识区自从被设立为一级分区后&#xff0c;B站就成了大家口中的“互联网大学”&#xff0c;有什么不懂的知识就习惯上B站搜一搜、查一查。根据B站官方出具的创作者报告数据显示&#xff0c;除了众多自发原创知识作品的UP主以外&#xff0c;还有超过300位名师学者加入B站&#x…

雅思积累(十八)同义替换

同义替换&#xff1a;sophisticated —— complicatedspecific —— detailed —— particularquantity —— wealth —— volume —— numbersettle —— schedule —— arrange —— fixswift —— rapid —— fast —— quickexpertise —— professional knowledge —— sk…

线程池的基本认识与使用

线程池的基本认识与使用线程池线程池工作原理&#xff1a;优点&#xff1a;传统的创建线程方式线程池创建线程使用线程池 池化思想&#xff1a;线程池、字符串常量池、数据库连接池可以提高资源的利用率 线程池工作原理&#xff1a; 预先创建多个线程对象 放入线程池种&#…

虚拟地址空间

本节目录1.如何理解区域划分2.为什么一个变量可以存储两个不同的值&#xff1f;3.深入理解虚拟地址空间为什么要有地址空间&#xff1f;4.理解什么是挂起&#xff1f;1.虚拟地址空间究竟是什么&#xff1f;2.映射关系的维护是谁做的&#xff1f;1.如何理解区域划分 所谓的区域…

笃行不怠勾勒人才图,望城区人才工作为高质量发展增添强劲动力

功以才成&#xff0c;业以才广。人才是经济高质量发展的重要资源。党的二十大报告明确“深入实施人才强国战略”&#xff0c;指出“实施更加积极、更加开放、更加有效的人才政策”。作为湖南“一核两副三带四区”区域经济发展格局的战略支点&#xff0c;望城区积极发挥着政策主…

2.单例模式

基本概念 单例模式&#xff1a;保证一个类只有一个实例&#xff0c;并提供一个访问该实例的全局访问点 常见应用场景 读取配置文件的类一般设计为单例模式网站计数器应用程序的日志应用&#xff0c;因为共享日志文件一直处于打开状态&#xff0c;只能有一个实例去操作Spring…

上传文件-课后程序(JAVA基础案例教程-黑马程序员编著-第九章-课后作业)

【案例9-3】 客户端向服务端上传文件 【案例介绍】 1.案例描述 编写一个客户端向服务端上传文件的程序&#xff0c;要求使用TCP通信的的知识&#xff0c;将本地机器输入的路径下的文件上传到D盘中名称为upload的文件夹中。并把客户端的IP地址加上count标识作为上传后文件的文…