Google FireBase - fcm 推送 (Cloud Messaging)
要将 Firebase 添加到您的应用,您需要有一个 Firebase 项目以及适用于您的应用的 Firebase 配置文件。
- 如果您还没有 Firebase 项目,请在 Firebase 控制台中创建一个。如果您已经有与自己的移动应用相关联的现有 Google 项目,请点击导入 Google 项目。如果没有,请点击添加项目。
- 点击将 Firebase 添加到您的 Android 应用,然后按设置步骤操作。如果您是导入现有 Google 项目,系统可能会自动执行这些操作,您只需下载配置文件即可。
- 出现提示时,输入应用的软件包名称。请务必输入应用在使用的软件包名称;只有在将应用添加到 Firebase 项目时您才能进行此设置。
- 最后,您要下载一个
google-services.json文件。您可以随时重新下载此文件。 - 如果尚未将此文件复制到项目的模块文件夹(通常是
app/),请执行此操作。
在“根级别”的build.gradle文件添加一条规则。以包含Google服务插件:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.google.gms:google-services:3.2.0'
}
}
allprojects {
repositories {
maven { url 'https://maven.google.com' }
mavenCentral()
jcenter()
}
}
然后在模块Gradle文件中(比如app模块下),底部添加apply plugin行,以启用 Gradle 插件:
apply plugin: 'com.android.application'
android {
// ...
}
dependencies {
// ...
compile 'com.google.android.gms:play-services-base:11.4.0'
// Google Firebase cloud messaging
compile 'com.google.firebase:firebase-messaging:11.4.0'
}
apply plugin: 'com.google.gms.google-services'
ECFCMMSGService 继承 FirebaseMessagingService , 重写onMessageReceived方法接收通知消息弹通知栏http请求:
https://fcm.googleapis.com/fcm/send Content-Type:application/json
Authorization:key= App Key
{
"notification" : {
"body" : "You have a new message",
"title" : "",
"icon" : "app icon"
},
"to" : "user token"
}
http请求:
https://fcm.googleapis.com/fcm/send Content-Type:application/json
Authorization:key= App Key
{
"data" : {
"request" : "1",
"xxx" : "xxx"
},
"to" : "user token"
}
(3)Messages with both notification and data payload:
这种消息是在Notification Message的基础上加入一些数据,在用户点击通知栏的时候启动对应的activity并传入intent。
public class ECFCMMSGService extends FirebaseMessagingService {
// 它主要用于处理接收 App 正在运行的时候,接收到的推送
private static final String TAG = "ECFCMMSGService";
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
sendNotification(remoteMessage.getNotification().getBody());
}
}
private void sendNotification(String messageBody) {
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("key", messageBody);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Bitmap icon2 = BitmapFactory.decodeResource(getResources(),
R.mipmap.app_logo);
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.app_logo)
.setContentTitle("You have a new message.")
.setContentText(messageBody)
.setAutoCancel(true)
.setLargeIcon(icon2)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(new Random().nextInt() /* ID of notification */, notificationBuilder.build());
}
}
自定义 ECFCMTokenRefreshService 集成 FirebaseInstanceIdService.
用户token的创建,转换和更新,在onTokenRefresh()方法中获取token并上传到服务器。
public class ECFCMTokenRefreshService extends FirebaseInstanceIdService {
// 它主要用于管理 FCM 的注册令牌(下文简称 FCM_TOKEN ),以及更改等。它可以获取到用户设备唯一的一个 FCM_TOKEN ,向单个用户推送消息的时候使用
private static final String TAG = "FCMTokenRefreshService";
private ApiService mService;
private float mRequestTime = 0;
private int mErrorCount = 0;
private int REQUEST_ERROR_MAX = 10;
private TreeMap<String, Object> mParams;
@Override
public void onCreate() {
super.onCreate();
if (PreferencesUtils.getInstance().isFCMTokenSendServiceSuccess()) {
return;
}
String token = PreferencesUtils.getInstance().getFcmToken();
if (TextUtils.isEmpty(token)) {
token = FirebaseInstanceId.getInstance().getToken();
}
sendFCMTokenToServer(token);
}
@Override
public void onTokenRefresh() {
super.onTokenRefresh();
PreferencesUtils.getInstance().saveFCMTokenSendServiceSuccess(false);
String token = FirebaseInstanceId.getInstance().getToken();
Log.i(TAG, "onTokenRefresh: " + token);
// Important, send the fcm token to the server
sendFCMTokenToServer(token);
}
// http://ebike-test.zriot.net/shop-app/push/token
private void sendFCMTokenToServer(final String token) {
if (TextUtils.isEmpty(token)) {
return;
}
if (mService == null) {
mService = RetrofitHelper.getInstance().getApiService(ApiService.class);
}
PreferencesUtils.getInstance().saveFCMToken(token);
if (!AccountManager.getInstance().isUserLogin()) {
return;
}
if (mParams == null) {
mParams = new TreeMap<>();
}
if (mParams.size() == 0) {
mParams.put("uid", AccountManager.getInstance().getUserId());
mParams.put("token", AccountManager.getInstance().getToken());
mParams.put("fcmToken", token);
mParams.put("osType", "1"); // 1: android 2 : ios }
mService.sendFCMTokenToServer(mParams)
.subscribeOn(Schedulers.io())
.unsubscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableObserverCallBack<BaseResponse>() {
@Override
public void onNext(@NonNull BaseResponse response) {
if (response == null) {
return;
}
if (response.isRequestSuccess()) {
PreferencesUtils.getInstance().saveFCMTokenSendServiceSuccess(true);
}
mErrorCount = 0;
}
@Override
public void onError(Throwable e) {
super.onError(e);
if (mErrorCount >= REQUEST_ERROR_MAX) {
return;
}
if (!allowRequest()) {
return;
}
sendFCMTokenToServer(token);
mErrorCount += 1;
}
});
}
private boolean allowRequest() {
if (mRequestTime == 0) {
mRequestTime = System.currentTimeMillis();
return true;
}
if (System.currentTimeMillis() - mRequestTime < 3000) {
return false;
} else {
mRequestTime = System.currentTimeMillis();
return true;
}
}
}
在android清单文件中:注册service:
<service android:name=".fcm.ECFCMMSGService"
android:stopWithTask="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service> <service android:name=".fcm.ECFCMTokenRefreshService"
android:stopWithTask="false">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
注意:
App 是否运行,决定了推送走的两条线路
App 在运行的时候,推送如果有 Notification ,一般也是我们自己去控制的,所以最终它点击后的效果,我们是可以通过 PendingIntent 做部分定制的。
但是如果是在 App 没有运行的情况下,就完全归 FCM 服务帮你完成这一系列的操作,它点击后的效果,只能将你的 App 调起,并且把你需要的参数传递到你的 SplashActivity(Action 为 android.intent.action.MAIN 的 Activity) 上。
推送服务的 icon 和 字体颜色
FCM 的推送通知,可以配置 icon 以及 App 名称的颜色。对 icon 和 字体颜色的配置,需要在 AndroidManifest.xml 中进行。
还有一点需要注意,通常我们 App 的 Icon 都做的非常的精美,但是这种 Icon 是无法直接使用在 FCM 的推送上的。需要额外的定制,以及对应的尺寸。
FCM Icon 的标准:背景透明,以白色图案填充。(实际上,展开后的效果会将icon 进行着色,所以任何颜色最终都会被着色成我们配置的颜色,不配置默认是个浅灰色)。

当然,它和图标的适配一样,不一定需要全套,只需要配置我们需要的尺寸即可。

将以下代码行添加到 application 标记内,以设置自定义默认图标和app 名称的自定义颜色:
<!-- 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" /> <!-- Set color used with incoming notification messages. This is used when no color is set for the incoming
notification message. See README(https://goo.gl/6BKBk7) for more. --> <meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorAccent" /> AndroidManifest.xml
如果配置好这些,依然得到的是一个白色的小块,可以尝试升级一下 FCM 的版本,低版本好像是有这个 Bug ,在新版已经解决了。
问题:
- Firebase API initialization failure.
- Android app not receiving Firebase Notification when app is stopped from multi-task tray
- Push notification works incorrectly when app is on background or not running
- Push not received when app is killed
Firebase控制台测试只能发送Notification Message,测试的时候把App从最近列表划掉之后能收到,而且是在没翻墙的情况下都能收到。当然当进程被完全杀死就收不到了。
Data Message则需要通过server api调用,前台后台都能收到透传消息。
Android Push Notifications using Firebase Cloud Messaging FCM & PHP
Google FireBase - fcm 推送 (Cloud Messaging)的更多相关文章
- google fcm 推送的流程
总结:1.给一个人推,能成功,2.给多个人推,有两种,一种是给组推,一种是给主题推,之前用的是组推,但是不成功,这里换成主题推: <?phpnamespace App\Http\Controll ...
- google的GCM推送使用简介
pom <!-- https://mvnrepository.com/artifact/com.google.gcm/gcm-server --> <dependency> & ...
- 使用GCM服务(Google Cloud Messaging)实现Android消息推送
最近在网上查了关于很多Android消息推送的资料,其中主要有四种方法. 1) 使用GCM服务(Google Cloud Messaging) 2) 使用XMPP协议(Openfire + Spark ...
- 海外 App 的推送服务,试试 FCM 吧!!!
> **版权声明:** > > **本账号发布文章均来自公众号,承香墨影(cxmyDev),版权归承香墨影所有.** > > **每周会统一更新到这里,如果喜欢,可关注公 ...
- PWA 推送实践
PWA 推送实践 最近公司内录任务的系统总是忘记录任务,而那个系统又没有通知,所以想要实现一个浏览器的通知功能,免得自己忘记录入任务. 前端实现通知的几种方式 想要实现通知,我们就需要有个客户端,对于 ...
- Android、iOS和Windows Phone中的推送技术
推送并不是什么新技术,这种技术在互联网时代就已经很流行了.只是随着进入移动互联网时代,推送技术显得更加重要.因为在智能手机中,推送从某种程度上,可以取代使用多年的短信,而且与短信相比,还可以向用户展示 ...
- 【Android应用开发】 推送原理解析 极光推送使用详解 (零基础精通推送)
作者 : octopus_truth 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/45046283 推送技术产生场景 : -- ...
- Android P正式版即将到来:后台应用保活、消息推送的真正噩梦
1.前言 对于广大Android开发者来说,Android O(即Android 8.0)还没玩热,Andriod P(即Andriod 9.0)又要来了. 下图上谷歌官方公布的Android P ...
- android系统和ios系统是如何实现推送的,ios为什么没有后台推送
ios系统为什么没有后台推送? iOS 为了真正地为用户体验负责,不允许应用在后台活动.有了这个限制,但是对于终端设备,应用又是有必要“通知”到达用户的,随时与用户主动沟通起来的(典型的如聊天应用). ...
随机推荐
- iTOP-4418开发板Android 5.1/4.4丨Linux + Qt5.7丨Ubuntu12.04系统
核心板参数 尺寸:50mm*60mm 高度:核心板连接器组合高度1.5mm PCB层数:6层PCB沉金设计 4418 CPU:ARM Cortex-A9 四核 S5P4418处理器 1.4GHz 68 ...
- 移动端底部fixed固定定位输入框ios下不兼容
简短记录下最近开发移动端项目碰到的小坑,产品需求做一个售后对话页面,底部固定输入框,和微信对话差不多,但是在ios下,fixed失效,输入框被虚拟键盘挡住,在安卓下是正常的. 尝试过网上说的很多方法, ...
- Burp插件开发——环境配置
最近打算开发个Burp插件,从网上各种地找资料学习.第一步就应该是环境配置,请见下文. (其实最重要的前提是你已经安装了Burp,否则下面的所有内容都是无稽之谈了. https://pan.baidu ...
- 【译】索引进阶(八):SQL SERVER唯一索引
[译注:此文为翻译,由于本人水平所限,疏漏在所难免,欢迎探讨指正] 原文链接:传送门. 在本章节我们检查唯一索引.唯一索引的特别之处在于它不仅提供了性能益处,而且提供了数据完整性益处.在SQL SER ...
- mysql性能优化分析 --- 上篇
概要 之前看过<高性能mysql>对mysql数据库有了系统化的理解,虽然没能达到精通,但有了概念,遇到问题时会有逻辑条理的分析; 问题 问题:公司xxx页面调用某个接口时,loading ...
- AI应用开发实战(转)
AI应用开发实战 - 从零开始配置环境 与本篇配套的视频教程请访问:https://www.bilibili.com/video/av24421492/ 建议和反馈,请发送到https://git ...
- 利用 Google Chart API 生成二维码大小不一致
大小不一致是由于 chl 参数内容不一样导致的,而 chs 参数只能指定生成图片的大小,不能指定生成具体二维码大小. 比如:https://chart.googleapis.com/chart?ch ...
- 安卓获取自有证书的SHA1码
如果使用自有证书, 请使用 jdk 中自带的 keytool 工具,查看证书信息命令: keytool -list -v -keystore {your_app}.keystore 例如:你的证书为t ...
- web---资源的下载及中文乱码问题
1.html网页,超链接交由Servlet处理 <!DOCTYPE html> <html lang="en"> <head> <meta ...
- L1-046 整除光棍 大数除法
L1-046 整除光棍(20 分) 这里所谓的"光棍",并不是指单身汪啦~ 说的是全部由1组成的数字,比如1.11.111.1111等.传说任何一个光棍都能被一个不以5结尾的奇数整 ...