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 为了真正地为用户体验负责,不允许应用在后台活动.有了这个限制,但是对于终端设备,应用又是有必要“通知”到达用户的,随时与用户主动沟通起来的(典型的如聊天应用). ...
随机推荐
- HDU-1028 Ignatius and the Princess III(生成函数)
题意 给出$n$,问用$1$到$n$的数字问能构成$n$的方案数 思路 生成函数基础题,$x^{n}$的系数即答案. 代码 #include <bits/stdc++.h> #define ...
- net core appsetting配置
public class BaseController : Controller { protected WLEntity _db; protected ILogger _log; protected ...
- chrome浏览器开发常用快捷键之基础篇-遁地龙卷风
1.标签页和窗口快捷键 打开新的标签页,并跳转到该标签页 Ctrl + t 重新打开最后关闭的标签页,并跳转到该标签页 Ctrl + Shift + t 跳转到下一个打开的标签页 Ctrl + PgD ...
- python爬虫得到unicode编码处理方式
在用python做爬虫的时候经常会与到结果中包含unicode编码,需要将结果转化为中文,处理方式如下 str.encode('utf-8').decode('unicode_escape')
- gitlab安装后吃内存的解决办法
修改配置文件/etc/gitlab/gitlab.rb 将注释掉的这一行放开(至少为2,大致算法为cpu core数量*2 +1) # unicorn[ 然后执行如下命令: gitlab-ctl re ...
- 题解-POI2014 Supercomputer
Problem 辣鸡bzoj权限题,洛谷链接 题意概要:一棵 \(n\) 个点有根树.\(Q\) 次询问给出一个 \(K\),回答遍历完整棵树所需最少操作次数.每次操作可以选择访问不超过 \(K\) ...
- 前端笔记知识点整合之JavaScript(一)初识JavaScript
一.JavaScript简介 1.1网页分层 web前端一共分三层: 结构层 HTML : 负责搭建页面结构 样式层 CSS : 负责页面的美观 行为层 JavaSc ...
- 关于/tmp/ 目录自动清理文件
问题:今天开发人员给我说了一个错误:The temporary upload location [/tmp/tomcat.1337767218595042057.80/work/Tomcat/loca ...
- Unity简单塔防游戏的开发——敌人移动路径的创建及移动
软件工程综合实践专题第一次作业 Unity呢是目前一款比较火热的三维.二维动画以及游戏的开发引擎,我也由于一些原因开始接触并喜爱上了这款开发引擎,下面呢是我在学习该引擎开发小项目时编写的一些代码的脚本 ...
- iOS unity 互相调用加载高德地图时
需要增加 mapView.delegate = self 这是一种设计模式,有的人称为代理,有的人称为委托,比如有A,B两个控制器,由A可以push到B,B可以pop回A,现在有一种情况,A中有一个l ...