Firebase 推送教程
Firebase 云信息传递 (FCM) 是 Google 官方提供的一种跨平台消息传递解决方案,可供免费、可靠地传递消息。
准备工作
- 注册成为 Firebase 开发者
在 Firebase Console 注册账号并登陆。 - 添加项目
点击 “添加项目”,填写项目名称和国家 / 地区。添加完成后进入项目。 - 添加应用
在此只演示安卓系统,点击 “Overview 概览” 页面的 “将 Firebase 添加到您的 Android 应用” 按钮。填写 Android 应用包名(不可更改),别名(选填),调试签名证书 SHA1(可选)。 - 下载配置文件
点击 “注册应用”,下载配置文件 “google-services.json”。(此配置文件也可以在 Overview 的右边设置中的 “项目设置” 中查看、下载。)
在 Android Studio 中切换到项目视图,查看项目根目录(即 app 目录),并将配置文件放入到此根目录下。
修改 Gradle:项目级 build.gradle(<project>/build.gradle
):
1
2
3
4
5
6buildscript {
dependencies {
// Add this line
classpath 'com.google.gms:google-services:3.1.0'
}
}
应用级 build.gradle(<project>/<app-module>/build.gradle
):
1
2
3...
// Add to the bottom of the file (一定要放最后)
apply plugin: 'com.google.gms.google-services'
按 IDE 中显示的栏中的 “立即同步”(Sync now)。
服务器端
本文使用 Python 作为服务器脚本语言。
PyFCM 源码:PyFCM
环境配置
pip 方式:pip install pyfcm
服务端主函数
1 | from pyfcm import FCMNotification |
Android 上的主题消息传递
在发布 / 订阅模式下,利用 FCM 主题消息传递功能,可以将消息发送至已经选择加入特定主题的多台设备。根据需要撰写主题消息,FCM 将处理消息路由并将消息可靠地传送至正确的设备。
关于主题,请注意以下事项:
- 主题消息传递不限制每个应用拥有的主题和订阅数。
- 目前,主题消息的有效负载不得超过 2KB。
- 主题消息传递最适合传递新闻、天气或其他可通过公开途径获得的信息等内容。
- 主题消息针对吞吐量(而非延迟)进行了优化。要将消息快速安全地传送到单台设备或小规模设备组,应将消息定位至注册令牌,而非主题。
- 如果需要向一位用户的多台设备发送消息,可考虑针对这些使用情形进行设备组消息传递。
设置消息的优先级
- 普通优先级:这是数据消息的默认优先级。普通优先级消息不会让休眠设备打开网络连接,为了省电,它们可能会被延迟传递。如果是对时间不太敏感的消息,例如新电子邮件通知或其他要同步的数据,建议选择普通传递优先级。
- 高优先级:这是通知消息的默认优先级。FCM 会立即尝试传递高优先级消息,允许 FCM 服务在可能的情况下唤醒休眠设备并打开与应用服务器的网络连接。例如,带有即时通讯、聊天或语音通话提醒功能的应用通常需要打开网络连接并确保 FCM 及时将消息传递给设备。如果消息属于时间关键型且需要用户立刻交互,请设置高优先级,但需要注意的是,将消息设置为高优先级会比普通优先级耗费更多电池电量。
有效值为 normal 和 high。
不可折叠消息和可折叠消息
不可折叠消息表示每一条消息都将被传递至设备。不可折叠消息可传递一些有用内容至手机应用,从而联系服务器以获取数据,这与 “ping” 相反。默认情况下,消息不可折叠,但通知消息(始终是可折叠消息)除外。
聊天消息或关键消息都是典型的不可折叠消息。例如,在 IM 应用中,可能想要传递每一条消息,因为它们的内容各不相同。
在不折叠的情况下,最多可存储 100 条消息。达到此限值后,所有存储的消息都将被舍弃。设备在重新联网后将收到一条特殊消息,提示已达到此上限。之后,应用可以正常处理该状况,一般情况下会请求与应用服务器完全同步。
可折叠消息在还未被传递至设备的情况下可能会被新消息替代。
两种常见的可折叠消息是 “发送以同步” 消息和通知消息。“发送以同步” 消息是一个 “ping”,它会告诉移动应用从服务器同步数据。为用户更新最新比分的体育应用就属于这种消息。只有最新的消息是相关的。
要将消息标记为可折叠,请在消息有效负载中添加 collapse_key 参数。FCM 允许应用服务器在任意指定时间内为每台设备使用最多 4 个不同的折叠键。也就是说,FCM 连接服务器可以为每台设备同时存储 4 条不同的可折叠 “发送以同步” 消息,每一条都含有不同的折叠键。如果超出此限值,FCM 将仅保留 4 个折叠键,具体保留哪几个不一定。
Android 客户端
官方集成文档:在 Android 上设置 Firebase 云消息传递客户端应用
将 Firebase 添加到 Android 项目
前提条件:
- 运行 Android 4.0 (Ice Cream Sandwich) 或更高版本以及 Google Play 服务 11.0.4 或更高版本的设备。
- Google 代码库中的 Google Play Services SDK,可通过 Android SDK Manager 获得。
- 最新版本的 Android Studio,1.5 版或更高版本。
如果使用最新版本的 Android Studio(2.2 版或更高版本),建议使用 Firebase 智能助理来将的应用关联至 Firebase。Firebase 智能助理可以关联现有的项目,或者为创建一个新项目,并自动安装任何必要的 Gradle 依赖项。
- 依次点击 Tools>Firebase 以打开 Assistant 窗口。
- 点击以展开所列功能之一(例如 Cloud Messaging),然后点击所提供的教程链接。
- 点击 Connect to Firebase 按钮以关联至 Firebase,并向应用添加必要的代码。
添加所需的依赖
- 向根项目级 build.gradle 文件添加规则,以纳入 Google 服务插件:
1
2
3
4
5
6
7buildscript {
// ...
dependencies {
// ...
classpath 'com.google.gms:google-services:3.1.0'
}
} - 在模块 Gradle 文件(通常是 app/build.gradle)中,在文件的底部添加 apply plugin 代码行,以启用 Gradle 插件:
1
2
3
4
5
6
7
8
9
10
11apply plugin: 'com.android.application'
android {
// ...
}
dependencies {
// ...
compile 'com.google.firebase:firebase-messaging:11.4.2' #修改为最新版本
compile 'com.google.android.gms:play-services-base:11.4.2' #修改为最新版本
}
// 一定要放在最底部
apply plugin: 'com.google.gms.google-services' - 如果 FCM 对于 Android 应用的功能至关重要,请务必在应用的 build.gradle 中设置 minSdkVersion 8 或更高版本。这可确保 Android 应用无法安装在不能让其正常运行的环境中。
修改应用清单 AndroidManifest.xml
- 一项继承 FirebaseMessagingService 的服务。如果希望在后台进行除接收应用通知之外的消息处理,则必须添加此服务。要接收前台应用中的通知、接收数据有效负载以及发送上行消息等,必须继承此服务。
1
2
3
4
5<service android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service> - 一项继承 FirebaseInstanceIdService 的服务,用于处理注册令牌的创建、轮替和更新。如果要发送至特定设备或者创建设备组,则必须添加此服务。
1
2
3
4
5<service android:name=".MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service> - (可选)在应用组件中,用于设置通知的默认图标、颜色和通知渠道(Android O 的新功能)的元数据元素。如果传入的消息未明确设置图标、颜色或通知渠道,则 Android 会使用这些值。
1
2
3
4
5
6<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_stat_ic_notification" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorAccent" />
获取设备注册令牌
初次启动应用时,FCM SDK 会为客户端应用实例生成一个注册令牌。如果希望定位至单台设备或创建设备组,则需要通过继承 FirebaseInstanceIdService 来访问此令牌。
令牌会在初始启动后生成,建议检索最新更新的注册令牌。
注册令牌可能会在发生下列情况时更改:
- 应用删除实例 ID
- 应用在新设备上恢复
- 用户卸载 / 重新安装应用
- 用户清除应用数据
- 检索当前注册令牌
如果需要检索当前令牌,调用 FirebaseInstanceId.getInstance ().getToken ()。如果令牌尚未生成,此方法将返回 null。 - 监控令牌的生成
每次生成新的令牌时,都会触发 onTokenRefresh 回调,因此,在上下文中调用 getToken 可以确保访问的是当前可用的注册令牌。确保已将服务添加到清单文件中,然后在 onTokenRefresh 的上下文中调用 getToken,并记录相应值,如下所示:
1
2
3
4
5
6
7
8
public void onTokenRefresh() {
// 获得注册令牌
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
// 后续操作,如发送令牌到服务器
sendRegistrationToServer(refreshedToken);
}
获取该令牌后,可以将其发送到应用服务器并进行存储。
检查 Google Play 服务
依靠 Play 服务 SDK 运行的应用在访问 Google Play 服务功能之前,应始终检查设备是否拥有兼容的 Google Play 服务 APK。建议在以下两个位置进行检查:主 Activity 的 onCreate () 方法中,及其 onResume () 方法中。在 onCreate () 中检查可确保该应用在检查成功之前无法使用。在 onResume () 中检查可确保当用户通过一些其他方式返回正在运行的应用(比如通过返回按钮)时,检查仍将继续进行。
如果设备没有兼容的 Google Play 服务版本,应用可以调用 GoogleApiAvailability.makeGooglePlayServicesAvailable(this)
,以便让用户从 Play 商店下载 Google Play 服务,需要 import com.google.android.gms.common.GoogleApiAvailability;
为客户端应用订阅主题
客户端应用可以订阅任何现有主题,也可创建新主题。当客户端应用订阅新的主题名称(Firebase 项目中尚不存在的名称)时,系统会在 FCM 中创建使用这个名称的新主题,随后任何客户端都可订阅该主题。
若要订阅某个主题,客户端应用需使用 FCM 主题名称调用 Firebase 云消息传递 subscribeToTopic ():FirebaseMessaging.getInstance().subscribeToTopic("news");
若要退订,客户端应用需使用主题名称调用 Firebase 云消息传递 unsubscribeFromTopic ()。
处理消息
要接收消息,使用继承 FirebaseMessagingService 的服务。重写 onMessageReceived 和 onDeletedMessages 回调。
在收到消息后的 10 秒内处理该消息。超过 10 秒后,Android 无法保证能够执行,并可能随时终止进程。如果应用需要更多时间来处理消息,使用 Firebase Job Dispatcher。
onMessageReceived 是为大多数消息类型提供的,但有以下例外情况:当应用在后台时送达的通知消息。在这种情况下,通知将传送至设备的系统任务栏。默认情况下,用户点按通知即可打开应用启动器。同时具备通知和数据有效负载的消息,无论应用在前台还是后台。在这种情况下,通知将传送至设备的系统任务栏,数据有效负载则传送至启动器 Activity 的 intent 的 extras 参数中。
应用状态 | 通知 | 数据 | 两者 |
---|---|---|---|
前台 | onMessageReceived | onMessageReceived | onMessageReceived |
后台 | 系统任务栏 | onMessageReceived | 通知:系统任务栏 数据:intent 的 extras 参数。 |
注意:当需要发送通知(和数据)但是又希望不需要用户打开通知消息的情况下进行其他操作,则可以只发送数据,但是在 onMessageReceived 函数中手动生成 notification。
重写 onMessageReceived
1 |
|
如果服务器只发送数据,但是需要应用主动生成通知则:
1 | public class MyFirebaseMessagingService extends FirebaseMessagingService { |
重写 onDeletedMessages
如果应用在连接了 FCM 的特定设备上的待处理消息过多(超过 100 条),或者设备已有一个月以上的时间没有连接 FCM,FCM 可能不会传送消息。
在这些情况下,可能会收到对 FirebaseMessagingService.onDeletedMessages () 的回调。
当应用实例收到此回调时,应该执行与应用服务器的完全同步。
如果在过去 4 周内未向该设备上的应用发送消息,FCM 将不会调用 onDeletedMessages ()。
处理后台应用中的通知消息
当应用位于后台时,Android 会将通知消息转发至系统任务栏。默认情况下,用户点按通知时将打开应用启动器。
这包括同时含有通知和数据有效负载的消息(以及从通知控制台发送的所有消息)。
在这些情况下,通知将传送至设备的系统任务栏,数据有效负载则传送至启动器 Activity 的 intent 的 extras 参数中。