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

当前回答

如果应用程序处于后台模式或非活动(被杀死),你点击通知,你应该在启动屏幕中检查有效载荷(在我的情况下,启动屏幕是MainActivity.java)。

在onCreate的mainactivity。java中检查Extras:

    if (getIntent().getExtras() != null) {
        for (String key : getIntent().getExtras().keySet()) {
            Object value = getIntent().getExtras().get(key);
            Log.d("MainActivity: ", "Key: " + key + " Value: " + value);
        }
    }

其他回答

试试这个:

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);
    }
}

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

但有时,如果你不能决定你收到的消息类型,你必须处理它。我把我的方法贴在这里。您刚刚实现了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)
    }
}

}

我也有同样的问题。使用“数据消息”而不是“通知”更容易。数据消息总是加载类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());
    }

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

你可以在主活动的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);
        }

}

我也有同样的问题。如果应用程序是前台-它会触发我的后台服务,我可以根据通知类型更新我的数据库。 但是,应用程序将转到后台-默认的通知服务将小心地向用户显示通知。

下面是我在后台识别应用程序并触发后台服务的解决方案,

public class FirebaseBackgroundService extends WakefulBroadcastReceiver {

  private static final String TAG = "FirebaseService";

  @Override
  public void onReceive(Context context, Intent intent) {
    Log.d(TAG, "I'm in!!!");

    if (intent.getExtras() != null) {
      for (String key : intent.getExtras().keySet()) {
        Object value = intent.getExtras().get(key);
        Log.e("FirebaseDataReceiver", "Key: " + key + " Value: " + value);
        if(key.equalsIgnoreCase("gcm.notification.body") && value != null) {
          Bundle bundle = new Bundle();
          Intent backgroundIntent = new Intent(context, BackgroundSyncJobService.class);
          bundle.putString("push_message", value + "");
          backgroundIntent.putExtras(bundle);
          context.startService(backgroundIntent);
        }
      }
    }
  }
}

在manifest.xml中

<receiver android:exported="true" android:name=".FirebaseBackgroundService" android:permission="com.google.android.c2dm.permission.SEND">
            <intent-filter>
                <action android:name="com.google.android.c2dm.intent.RECEIVE" />
            </intent-filter>
        </receiver>

在最新的android 8.0版本中测试了该解决方案。谢谢