要将 Firebase 添加到您的应用,您需要有一个 Firebase 项目以及适用于您的应用的 Firebase 配置文件。

  1. 如果您还没有 Firebase 项目,请在 Firebase 控制台中创建一个。如果您已经有与自己的移动应用相关联的现有 Google 项目,请点击导入 Google 项目。如果没有,请点击添加项目
  2. 点击将 Firebase 添加到您的 Android 应用,然后按设置步骤操作。如果您是导入现有 Google 项目,系统可能会自动执行这些操作,您只需下载配置文件即可。
  3. 出现提示时,输入应用的软件包名称。请务必输入应用在使用的软件包名称;只有在将应用添加到 Firebase 项目时您才能进行此设置。
  4. 最后,您要下载一个 google-services.json 文件。您可以随时重新下载此文件
  5. 如果尚未将此文件复制到项目的模块文件夹(通常是 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方法接收通知消息弹通知栏
FCM有两种消息: Data Message和 Notification Message.
(1)Notification Message :
只有app在前台的时候才会走这个方法,当app在后台的时候由系统弹通知栏,当app被杀死的时候,从Firebase后台发送是收不到的
 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"
}
(2)Data Message:
不管app在后台还是前台都会走这个方法。
 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控制台测试只能发送Notification Message,测试的时候把App从最近列表划掉之后能收到,而且是在没翻墙的情况下都能收到。当然当进程被完全杀死就收不到了。

Data Message则需要通过server api调用,前台后台都能收到透传消息。

Android Push Notifications using Firebase Cloud Messaging FCM & PHP

Google FireBase - fcm 推送 (Cloud Messaging)的更多相关文章

  1. google fcm 推送的流程

    总结:1.给一个人推,能成功,2.给多个人推,有两种,一种是给组推,一种是给主题推,之前用的是组推,但是不成功,这里换成主题推: <?phpnamespace App\Http\Controll ...

  2. google的GCM推送使用简介

    pom <!-- https://mvnrepository.com/artifact/com.google.gcm/gcm-server --> <dependency> & ...

  3. 使用GCM服务(Google Cloud Messaging)实现Android消息推送

    最近在网上查了关于很多Android消息推送的资料,其中主要有四种方法. 1) 使用GCM服务(Google Cloud Messaging) 2) 使用XMPP协议(Openfire + Spark ...

  4. 海外 App 的推送服务,试试 FCM 吧!!!

    > **版权声明:** > > **本账号发布文章均来自公众号,承香墨影(cxmyDev),版权归承香墨影所有.** > > **每周会统一更新到这里,如果喜欢,可关注公 ...

  5. PWA 推送实践

    PWA 推送实践 最近公司内录任务的系统总是忘记录任务,而那个系统又没有通知,所以想要实现一个浏览器的通知功能,免得自己忘记录入任务. 前端实现通知的几种方式 想要实现通知,我们就需要有个客户端,对于 ...

  6. Android、iOS和Windows Phone中的推送技术

    推送并不是什么新技术,这种技术在互联网时代就已经很流行了.只是随着进入移动互联网时代,推送技术显得更加重要.因为在智能手机中,推送从某种程度上,可以取代使用多年的短信,而且与短信相比,还可以向用户展示 ...

  7. 【Android应用开发】 推送原理解析 极光推送使用详解 (零基础精通推送)

    作者 : octopus_truth 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/45046283 推送技术产生场景 : -- ...

  8. Android P正式版即将到来:后台应用保活、消息推送的真正噩梦

    1.前言 对于广大Android开发者来说,Android O(即Android 8.0)还没玩热,Andriod P(即Andriod 9.0)又要来了.   下图上谷歌官方公布的Android P ...

  9. android系统和ios系统是如何实现推送的,ios为什么没有后台推送

    ios系统为什么没有后台推送? iOS 为了真正地为用户体验负责,不允许应用在后台活动.有了这个限制,但是对于终端设备,应用又是有必要“通知”到达用户的,随时与用户主动沟通起来的(典型的如聊天应用). ...

随机推荐

  1. 工作经验-PLSQL连接远程数据库

    复制远程Oracle,tnsnames.ora 放到[D:\OneDrive\PLSQL\instantclient_11_2\network\admin] PLSQL->Tools > ...

  2. makefile 嵌套

    目录结构: dynamic 和 static 两个目录实现加法功能, 分别生成动态库和静态库,   main.c 主文件链接加法功能,  终端命令执行:   make dynamic=1  则编译动态 ...

  3. Angular_上拉刷新

    1.先不做上拉触发,用button模拟一下,触发函数 export class StudyComponent implements OnInit { /*列表数据流 */ list$: Observa ...

  4. python 识别图片文字

    今天群里有兄弟问如何把图片的文字给识别出来 对于python来说这不是小菜一碟吗,于是乎让pupilheart狠狠的吹了一波(哈哈,竟然没懂),下面将整个实现过程给大家实现下: 方法一:自己搞定ORC ...

  5. Mock.js简易教程,脱离后端独立开发,实现增删改查功能(转)

    在我们的生产实际中,后端的接口往往是较晚才会出来,并且还要写接口文档,于是我们的前端的许多开发都要等到接口给我们才能进行,这样对于我们前端来说显得十分的被动,于是有没有可以制造假数据来模拟后端接口呢, ...

  6. linux的cron

    linux系统由cron(crond)这个系统服务来控制的,linux系统上原来有非常多的计划性工作,因此,这个系统服务是默认启动的.cron进程每分钟会定期检查是否有要执行的任务,如果有就自动执行该 ...

  7. Js获取客户端用户Ip地址

    利用搜狐查询接口查询Ip地址: <!DOCTYPE html> <html> <head> <meta charset="utf-8" / ...

  8. 基于Vue2.x的小米商城移动端项目

    初学vue已经有一段时间,为了检验自己的学习成果,决定做一个项目作为一个阶段性总结,项目花了差不多半个月时间,目前实现了7个页面,商城的主要功能基本实现,代码已经放到github上面. 这个项目把大部 ...

  9. 使用Anaconda操作numpy库和matplotlib图形库

    慢慢来~~~ import numpy as np import matplotlib.pyplot as plt # 生成数据 x = np.arange(0, 6, 0.1) # 以0.1为单位, ...

  10. ASP.NET Core快速入门学习笔记(第2章:配置管理)

    课程链接:http://video.jessetalk.cn/course/explore 良心课程,大家一起来学习哈! 任务9:配置介绍 命令行配置 Json文件配置 从配置文件文本到c#对象实例的 ...