这是我的舱单:
<service android:name=".fcm.PshycoFirebaseMessagingServices">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".fcm.PshycoFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
当应用程序在后台和通知到达,然后默认通知来,不运行我的onmessagerreceived代码。
这是我的onMessageReceived代码。如果我的应用程序在前台运行,而不是在后台运行,就会调用这个函数。我怎么能运行这段代码时,应用程序是在后台太?
// [START receive_message]
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO(developer): Handle FCM messages here.
// If the application is in the foreground handle both data and notification messages here.
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
data = remoteMessage.getData();
String title = remoteMessage.getNotification().getTitle();
String message = remoteMessage.getNotification().getBody();
String imageUrl = (String) data.get("image");
String action = (String) data.get("action");
Log.i(TAG, "onMessageReceived: title : "+title);
Log.i(TAG, "onMessageReceived: message : "+message);
Log.i(TAG, "onMessageReceived: imageUrl : "+imageUrl);
Log.i(TAG, "onMessageReceived: action : "+action);
if (imageUrl == null) {
sendNotification(title,message,action);
} else {
new BigPictureNotification(this,title,message,imageUrl,action);
}
}
// [END receive_message]
根据firebase文档在发送下游使用firebase,有两种类型的有效载荷:
数据
此参数指定消息有效负载的自定义键-值对。
客户端应用程序负责处理数据消息。数据消息只有自定义键值对。
通知
此参数指定通知有效负载的预定义的、用户可见的键-值对。FCM自动代表客户端应用程序将消息显示给最终用户设备。通知消息具有一组预定义的用户可见键。
当你在前台时,你可以使用onmessagerecreceived()在FCM内部获取数据,你可以从数据有效载荷中获取数据。
data = remoteMessage.getData();
String customData = (String) data.get("customData");
当您在后台时,FCM将根据通知有效载荷的信息在系统托盘中显示通知。系统托盘上用于通知的标题、消息和图标都来自通知有效负载。
{
"notification": {
"title" : "title",
"body" : "body text",
"icon" : "ic_notification",
"click_action" : "OPEN_ACTIVITY_1"
}
}
当你想在应用程序处于后台时自动在系统托盘上显示通知时,使用这个通知有效载荷。
当你的应用程序在后台运行时,为了获得通知数据,你应该在通知有效载荷中添加click_action。
如果你想打开你的应用并执行一个特定的动作(在后台),在通知有效载荷中设置click_action,并将其映射到你想要启动的Activity中的意图过滤器。例如,将click_action设置为OPEN_ACTIVITY_1来触发一个意图过滤器,如下所示:
<intent-filter>
<action android:name="OPEN_ACTIVITY_1" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
把intent-filter放在你的清单上,在你的一个activity标签里面。当你点击通知时,它将打开应用程序并直接进入你在click_action中定义的活动,在本例中为“OPEN_ACTIVTY_1”。
在这个活动中,你可以通过以下方式获取数据:
Bundle b = getIntent().getExtras();
String someData = b.getString("someData");
我使用FCM为我的android应用程序和使用两个有效载荷。
下面是我使用的JSON示例:
{
"to": "FCM registration ID",
"notification": {
"title" : "title",
"body" : "body text",
"icon" : "ic_notification",
"click_action" : "OPEN_ACTIVITY_1"
},
"data": {
"someData" : "This is some data",
"someData2" : "etc"
}
}
自2019年以来,谷歌Firebase的api有了很大的变化
我的意思是:
“com.google.firebase: firebase-messaging: 18.0.0”
在18.0.0中,他们删除了MyFirebaseInstanceIDService,你需要在MyFirebaseMessagingService中获取令牌,所以你只需要写:
@Override
public void onNewToken(String token) {
Log.d(TAG, "Refreshed token: " + token);
}
在你的AndroidManifest.xml中,你必须删除:
<service android:name=".service.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
此外,建议您设置默认值以自定义通知的外观。您可以指定自定义默认图标和自定义默认颜色,在通知有效负载中没有设置等效值时应用它们。
在应用程序标记中添加这些行来设置自定义默认图标和自定义颜色:
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="@drawable/ic_notification" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="@color/colorAccent" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="@string/push_channel" />
现在要在后台应用程序中处理通知消息,你应该在你的第一个Activity中定义一个Intent,即使它是SplashScreen。当你的应用程序在后台时,Android将通知消息定向到系统托盘。用户点击通知会默认打开应用启动器。
例如,如果你的Json是这样的:
"data": {
"message": "2",
"title": "1",
"pushType" : "banner",
"bannerLink": "http://www.google.com",
"image" : "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png"}
你只需要写一个简单的意图来获取这些值:
Bundle extras = intent.getExtras();
String bannerLink = extras.getString("bannerLink");
...
String channelId = extras.getString("channelId");
根据文件
Handle messages in a backgrounded app
When your app is in the background, Android directs notification
messages to the system tray. A user tap on the notification opens the
app launcher by default.
This includes messages that contain both notification and data
payload. In these cases, the notification is delivered to the device's
system tray, and the data payload is delivered in the extras of the
intent of your launcher Activity.
If you want to open your app and perform a specific action, set
click_action in the notification payload and map it to an intent
filter in the Activity you want to launch. For example, set
click_action to OPEN_ACTIVITY_1 to trigger an intent filter like the
following:
<intent-filter> <action android:name="OPEN_ACTIVITY_1" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
编辑:
基于这个线程:
不能使用Firebase Console设置click_action有效负载。您可以尝试使用curl命令或自定义http服务器进行测试
curl --header "Authorization: key=<YOUR_KEY_GOES_HERE>"
--header Content-Type:"application/json" https://fcm.googleapis.com/fcm/send
-d "{\"to\":\"/topics/news\",\"notification\":
{\"title\": \"Click Action Message\",\"text\": \"Sample message\",
\"click_action\":\"OPEN_ACTIVITY_1\"}}"
此情况仅用于firebase管理通知
如果应用程序在后台,则不会触发FirebaseMessagingService
要处理这种情况,请转到launcher activity,检查附加的intent bundle,并使用以下代码打印出所有数据:
intent?.extras?.let {it->
for (key in bundle.keySet()) {
val value = bundle[key]
Log.d("NotificationData", String.format("%s %s (%s)", key, value.toString(), value!!.javaClass.name))
}
}
显示所有数据类型的签入日志;
例子:
我想从通知中获得周和标题将使用这段代码
intent?.extras?.let {it->
if (it.containsKey("week")){
}
if (it.containsKey("title")){
}
1. 为什么会这样?
FCM (Firebase Cloud Messaging)中有两种类型的消息:
显示消息:这些消息仅在应用程序处于前台时触发onmessagerreceived()回调
数据消息:这些消息触发onmessagerreceived()回调,即使你的应用程序在前台/后台/被杀死
注意:Firebase团队还没有开发用于发送数据消息的UI
还有你的设备。您应该使用您的服务器发送这种类型!
2. 如何?
为了实现这一点,你必须对以下URL执行POST请求:
文章https://fcm.googleapis.com/fcm/send
头
关键字:Content-Type,值:application/json
Key: Authorization, Value: Key =<your-server-key>
主体使用主题
{
"to": "/topics/my_topic",
"data": {
"my_custom_key": "my_custom_value",
"my_custom_key2": true
}
}
或者如果你想把它发送到特定的设备
{
"data": {
"my_custom_key": "my_custom_value",
"my_custom_key2": true
},
"registration_ids": ["{device-token}","{device2-token}","{device3-token}"]
}
注意:请确保您没有添加JSON键通知
注意:要获得服务器密钥,您可以在firebase控制台中找到它:您的项目->设置->项目设置->云消息传递->服务器密钥
3.如何处理推送通知消息?
这是你如何处理收到的消息:
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> data = remoteMessage.getData();
String myCustomKey = data.get("my_custom_key");
// Manage data
}