这是我的舱单:
<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-messaging-sw.js中添加了以下代码,
messaging.onBackgroundmessage((payload)=>{
console.log("background message detected!!");
console.log("message : ", payload);
})
这是触发每次消息接收在后台。但我无法在主线程中使用有效负载,因为SW不支持它。所以我做了很多研究,在一个Android论坛上找到了一个解决方案。
因此,解决方案是必须从请求有效负载中删除通知有效负载。
所以我把有效载荷从
{
"notification": {
"title": "Hey there",
"body": "Subscribe to AMAL MOHAN N youtube channel"
},
"to": "your-browser-token",
"data": {
"value1": "text",
"value2": "",
"value3": "sample3",
"value4": "sample4"
}
}
to
{
"to": "your-browser-token",
"data": {
"value1": "text",
"value2": "",
"value3": "sample3",
"value4": "sample4"
}
}
有效负载的变化会自动在前台消息和后台消息中触发receiveMessage()。
我在一个Android论坛上发现了这个,这对我来说很有用!如果这对你有用,请告诉我。
感谢你们所有人的回答。但是我通过发送数据消息而不是发送通知来解决这个问题。
服务器代码
<?php
$url = "https://fcm.googleapis.com/fcm/send";
$token = "C-l6T_a7HouUK****";
$serverKey = "AAAAaOcKS00:********";
define( 'API_ACCESS_KEY', $serverKey );
$registrationIds = array($token);
// prep the bundle
$msg = array
(
'message' => 'here is a message. message',
'title' => 'This is a title. title',
'subtitle' => 'This is a subtitle. subtitle',
'tickerText' => 'Ticker text here...Ticker text here...Ticker text
here',
'vibrate' => 1,
'sound' => 1,
'largeIcon' => 'large_icon',
'smallIcon' => 'small_icon'
);
$fields = array
(
'registration_ids' => $registrationIds,
'data' => $msg
);
$headers = array
(
'Authorization: key=' . API_ACCESS_KEY,
'Content-Type: application/json'
);
$ch = curl_init();
curl_setopt( $ch,CURLOPT_URL, 'https://android.googleapis.com/gcm/send'
);
curl_setopt( $ch,CURLOPT_POST, true );
curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers );
curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true );
curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) );
$result = curl_exec($ch );
curl_close( $ch );
echo $result;
?>
并在onmessagerreceived中捕获数据
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
sendNotification(remoteMessage.getData().get("message"));
}
// Check if message contains a notification payload.
else 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, Notify.class).putExtra("msg",messageBody);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
String channelId = "idddd";
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(MyFirebaseMessagingService.this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("FCM Message")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
根据文件
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\"}}"
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
}