我正在使用Firebase并测试在应用程序处于后台时从服务器发送通知到我的应用程序。通知发送成功,它甚至出现在设备的通知中心,但当通知出现或即使我点击它,我的FCMessagingService中的onmessagerreceived方法永远不会被调用。
当我测试这个,而我的应用程序是在前台,onmessagerreceived方法被调用,一切工作正常。问题发生在应用程序在后台运行时。
这是我有意为之的行为吗,或者我有办法解决这个问题吗?
这是我的FBMessagingService:
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
public class FBMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.i("PVL", "MESSAGE RECEIVED!!");
if (remoteMessage.getNotification().getBody() != null) {
Log.i("PVL", "RECEIVED MESSAGE: " + remoteMessage.getNotification().getBody());
} else {
Log.i("PVL", "RECEIVED MESSAGE: " + remoteMessage.getData().get("message"));
}
}
}
如果应用程序在后台Fire-base默认处理通知,但如果我们想要我们的自定义通知,那么我们必须改变我们的服务器端,它负责发送我们的自定义数据(数据有效载荷)
从服务器请求中完全删除通知有效负载。只发送数据并在onmessagerecreceived()中处理它,否则当应用程序在后台或被杀死时,你的onmessagerecreceived将不会被触发。
现在,你的服务器端代码格式是这样的,
{
"collapse_key": "CHAT_MESSAGE_CONTACT",
"data": {
"loc_key": "CHAT_MESSAGE_CONTACT",
"loc_args": ["John Doe", "Contact Exchange"],
"text": "John Doe shared a contact in the group Contact Exchange",
"custom": {
"chat_id": 241233,
"msg_id": 123
},
"badge": 1,
"sound": "sound1.mp3",
"mute": true
}
}
注意:参见上面代码中的这一行
"text": "John Doe在群组联系人交换中共享了一个联系人"
在数据有效载荷中,你应该使用“文本”参数而不是“正文”或“消息”参数来描述消息或任何你想使用文本的内容。
onMessageReceived ()
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.e(TAG, "From: " + remoteMessage.getData().toString());
if (remoteMessage == null)
return;
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
/* Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());*/
Log.e(TAG, "Data Payload: " + remoteMessage);
try {
Map<String, String> params = remoteMessage.getData();
JSONObject json = new JSONObject(params);
Log.e("JSON_OBJECT", json.toString());
Log.e(TAG, "onMessageReceived: " + json.toString());
handleDataMessage(json);
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
}
}
}
{
"notification": {
"title": "Notification Title",
"body": "Notification Body",
"click_action": "ActivityToOpen"
},
"data": {
"key": "value "
},
"to": "id"
}
如果FCM负载有如上的notification{}块,并且应用程序在后台,系统会用notification{}中给出的标题和正文为你构建通知。当用户单击它时,click_action中提到的活动将打开,如果没有给出任何默认启动器活动,则可以访问data{}块中的数据
intent.extras // of the launcher activity
如果应用程序在前台,则会触发FirebaseMessagingService()类中的onMessageReceived()函数。我们将不得不建立自己的通知,我们可以访问数据如下:
val value = message.data.getOrDefault("key", "")
如果FCM负载没有通知块{},如下所示;
{
"data": {
"title": "Notification Title",
"body": "Notification Body",
"key": "value "
},
"to" : "id"
}
函数onmessagerecreceived()在FirebaseMessagingService()类被触发,无论应用程序是在后台或前台,我们将不得不建立自己的通知。
我们可以通过以下方式访问数据:
override fun onMessageReceived(message: RemoteMessage) {
super.onMessageReceived(message)
val title = message.data.getOrDefault("title", "")
val body = message.data.getOrDefault("body", "")
}
我也有同样的问题。使用“数据消息”而不是“通知”更容易。数据消息总是加载类onmessagerreceived。
在该类中,您可以使用notificationbuilder创建自己的通知。
例子:
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
sendNotification(remoteMessage.getData().get("title"),remoteMessage.getData().get("body"));
}
private void sendNotification(String messageTitle,String messageBody) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0 /* request code */, intent,PendingIntent.FLAG_UPDATE_CURRENT);
long[] pattern = {500,500,500,500,500};
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_name)
.setContentTitle(messageTitle)
.setContentText(messageBody)
.setAutoCancel(true)
.setVibrate(pattern)
.setLights(Color.BLUE,1,1)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}