我正在使用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"));
        }
    }
}

当前回答

{
      "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", "")
}

其他回答

我认为告诉您将消息类型更改为数据的答案对您来说很清楚。

但有时,如果你不能决定你收到的消息类型,你必须处理它。我把我的方法贴在这里。您刚刚实现了FirebaseMessagingService并在handlIntent()方法中处理您的消息。从那里你可以自定义你自己的通知。你可以实现你自己的方法sendYourNotificatoin()

class FCMPushService : FirebaseMessagingService() {

companion object {
    private val TAG = "FCMPush"
}



override fun handleIntent(intent: Intent?) {
    Logger.t(TAG).i("handleIntent:${intent.toString()}")
    val data = intent?.extras as Bundle
    val remoteMessage = RemoteMessage(data)

    if (remoteMessage.data.isNotEmpty()) {
        val groupId: String = remoteMessage.data[MESSAGE_KEY_GROUP_ID] ?: ""
        val title = remoteMessage.notification?.title ?: ""
        val body =  remoteMessage.notification?.body ?: ""
        if (title.isNotEmpty() && body.isNotEmpty())
            sendYourNotificatoin(this, title, body, groupId)
    }
}

}

我有这个问题(应用程序不想打开通知点击,如果应用程序是在后台或关闭),问题是在通知主体无效的click_action,尝试删除或更改为有效的东西。

试试这个:

public void handleIntent(Intent intent) {
    try {
        if (intent.getExtras() != null) {
            RemoteMessage.Builder builder = new RemoteMessage.Builder("MyFirebaseMessagingService");
            for (String key : intent.getExtras().keySet()) {
            builder.addData(key, intent.getExtras().get(key).toString());
        }
            onMessageReceived(builder.build());
        } else {
            super.handleIntent(intent);
        }
    } catch (Exception e) {
        super.handleIntent(intent);
    }
}

当消息收到,你的应用程序是在后台通知被发送到额外的意图的主要活动。

你可以在主活动的oncreate()或onresume()函数中检查额外的值。

您可以检查字段,如数据,表等(在通知中指定的)

例如,我发送使用数据作为关键

public void onResume(){
    super.onResume();
    if (getIntent().getStringExtra("data")!=null){
            fromnotification=true;
            Intent i = new Intent(MainActivity.this, Activity2.class);
            i.putExtra("notification","notification");
            startActivity(i);
        }

}

这是预期的工作,通知消息只有当你的应用程序在前台时才被传递到你的onmessagerreceived回调。如果你的应用程序在后台或关闭,那么通知中心会显示一条通知消息,来自该消息的任何数据都会传递给意图,而用户点击通知的结果就是启动该消息。

您可以在JSON中指定click_action,以指示当用户点击通知时应该启动的意图。如果没有指定click_action,则使用主活动。

当意图启动时,你可以使用

getIntent().getExtras();

检索包含随通知消息一起发送的任何数据的Set。

有关通知消息的更多信息,请参阅文档。