-->

App not showing Notification receiving FCM when th

2020-08-22 03:05发布

问题:

When I send a push from Firebase, if the app is in background or closed, I'm receiving the notification, but when the app is open not...

Debugging I've observed that it's stopping in MyMessagingService specifically at onMessageReceived, so I guess that my problem is in regards of generating the notification (or maybe the intent which goes with the notification).

I've implemented the service:

public class MyMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyMessagingService";
@Override
public void onMessageReceived(RemoteMessage remoteMessage)
{
    Log.d(TAG, "From: " + remoteMessage.getFrom());

    if(remoteMessage!=null)
    {
        String id = null;
        String title = null;
        String message = null;
        String launchPage = null;

        if(remoteMessage.getNotification()!=null)
        {
            if(remoteMessage.getNotification().getTitle()!=null)
            {
                title = remoteMessage.getNotification().getTitle();
            }

            if(remoteMessage.getNotification().getBody()!=null)
            {
                message = remoteMessage.getNotification().getBody();
            }
        }

        if(remoteMessage.getMessageId()!=null)
        {
            id = remoteMessage.getMessageId();
        }

        Log.e(TAG, "id: " + id);
        Log.e(TAG, Consts.TITLE + title);
        Log.e(TAG, Consts.MESSAGE + ": " + message);

        // Check if message contains a data payload.
        if (remoteMessage.getData()!=null && remoteMessage.getData().size() > 0)
        {
            Log.d(TAG, "Message data payload: " + remoteMessage.getData());

            if(remoteMessage.getData().containsKey(Consts.LAUNCH_PAGE))
            {
                launchPage = remoteMessage.getData().get(Consts.LAUNCH_PAGE);
            }

            Log.e(TAG, Consts.LAUNCH_PAGE + ": " + launchPage);

            sendNotification(title, message, launchPage);

        }
    }
}
// [END receive_message]

/**
 * Create and show a simple notification containing the received FCM message.
 *
 * @param messageBody FCM message body received.
 */
private void sendNotification(String title, String messageBody, String page)
{
    Intent intent = new Intent(this, MainActivity.class);

    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

    intent.putExtra(Consts.TITLE, title);
    intent.putExtra(Consts.MESSAGE, messageBody);
    if (launchPage != null)
    {
        intent.putExtra(Consts.LAUNCH_PAGE, launchPage);
    }

    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT);

    String channelId = getString(R.string.default_notification_channel_id);
    Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    NotificationCompat.Builder notificationBuilder =
            new NotificationCompat.Builder(this, channelId)
            .setSmallIcon(R.drawable.status)
            .setContentTitle(title)
            .setContentText(messageBody)
            .setAutoCancel(true)
            .setSound(defaultSoundUri)
            .setContentIntent(pendingIntent);

    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
} }

In my manifest I have:

 <!-- [START fcm_default_icon] -->
    <meta-data
        android:name="com.google.firebase.messaging.default_notification_icon"
        android:resource="@drawable/status" />

    <meta-data
        android:name="com.google.firebase.messaging.default_notification_color"
        android:resource="@color/accent" />
    <!-- [END fcm_default_icon] -->
    <!-- [START fcm_default_channel] -->
    <meta-data
        android:name="com.google.firebase.messaging.default_notification_channel_id"
        android:value="@string/default_notification_channel_id"/>
    <!-- [END fcm_default_channel] -->

    <service
        android:name=".controller.service.MyMessagingService">
        <intent-filter>
            <action android:name="com.google.firebase.MESSAGING_EVENT"/>
        </intent-filter>
    </service>

    <service
        android:name=".controller.service.MyInstanceIDService">
        <intent-filter>
            <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
        </intent-filter>
    </service>

Any suggestion of how to generate the notification when the app is en foreground?

回答1:

Change your MyFirebaseMessagingService code,

public class MyFirebaseMessagingService extends FirebaseMessagingService {

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    super.onMessageReceived(remoteMessage);
    Log.d("msg", "onMessageReceived: " + remoteMessage.getData().get("message"));

        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
        String channelId = "Default";
        NotificationCompat.Builder builder = new  NotificationCompat.Builder(this, channelId)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle(remoteMessage.getNotification().getTitle())
                .setContentText(remoteMessage.getNotification().getBody()).setAutoCancel(true).setContentIntent(pendingIntent);;
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(channelId, "Default channel", NotificationManager.IMPORTANCE_DEFAULT);
            manager.createNotificationChannel(channel);
        }
        manager.notify(0, builder.build());
     }
 }

check - How to handle the fire base notification when app is in foreground



回答2:

When app is in background, your service is not even called if message contains notification. Firebase service client processes the notifications and displays it. That is why it working.

First, debug it when app is foreground and make sure you are receiving both notification and data in the notification from FCM.

If it looks good, it could be that time to process the notification in service exceeding the time limit, try moving the processing of notification in onMessageReceived to background thread. See here is an example http://www.zoftino.com/android-notification-data-messages-from-app-server-using-firebase-cloud-messaging



回答3:

I finally fixed the issue, it was a problem of how I created the notification, so this is my code:

private void sendNotification(String title, String messageBody, String page)
{
    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext(), getString(R.string.default_notification_channel_id));
    Intent intent = new Intent(getApplicationContext(), MainActivity.class);

    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.putExtra(Consts.TITLE, title);
    intent.putExtra(Consts.MESSAGE, messageBody);

    if (page != null)
    {
        intent.putExtra(Consts.LAUNCH_PAGE, page);
    }

    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);

    NotificationCompat.BigTextStyle bigText = new NotificationCompat.BigTextStyle();
    bigText.bigText(title);
    bigText.setBigContentTitle(messageBody);

    mBuilder.setContentIntent(pendingIntent);
    mBuilder.setSmallIcon(R.drawable.status);
    mBuilder.setContentTitle(title);
    mBuilder.setContentText(messageBody);
    mBuilder.setPriority(Notification.PRIORITY_MAX);
    mBuilder.setAutoCancel(true);
    mBuilder.setStyle(bigText);

    NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
    {
        NotificationChannel channel = new NotificationChannel(getString(R.string.default_notification_channel_id), getString(R.string.default_notification_channel_name), NotificationManager.IMPORTANCE_DEFAULT);
        mNotificationManager.createNotificationChannel(channel);
    }

    mNotificationManager.notify(0, mBuilder.build());
}

Hope this can help anyone else. Thanks for the replays.



回答4:

@SuppressLint("WrongConstant")
    private void showNotification(String message) {
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
        Intent resultIntent = new Intent(getApplicationContext(), SplashActivity.class);
        resultIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        resultIntent.setFlags(Notification.FLAG_AUTO_CANCEL);
        PendingIntent intent = PendingIntent.getActivity(getApplicationContext(), 0, resultIntent, 0);
        mBuilder.setSmallIcon(R.drawable.app_icon);
        mBuilder.setContentTitle("App Name");
        mBuilder.setContentText(message);
        Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.app_icon);
        mBuilder.setLargeIcon(icon);
        mBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(message));
        mBuilder.setAutoCancel(true);
        mBuilder.setPriority(Notification.PRIORITY_HIGH);
        mBuilder.setDefaults(Notification.DEFAULT_LIGHTS);
        mBuilder.setDefaults(Notification.DEFAULT_ALL);

        if (Build.VERSION.SDK_INT> Build.VERSION_CODES.KITKAT)
        {
            mBuilder.setCategory(Notification.CATEGORY_MESSAGE);
        }
        mBuilder.setContentIntent(intent);
        NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.notify(1, mBuilder.build());

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            int importance = NotificationManager.IMPORTANCE_HIGH;
            NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "NOTIFICATION_CHANNEL_NAME", importance);
            notificationChannel.enableLights(true);
            notificationChannel.setLightColor(Color.RED);
            notificationChannel.enableVibration(true);
            notificationChannel.setShowBadge(false);
            notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
            assert mNotificationManager != null;
            mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID);
            mNotificationManager.createNotificationChannel(notificationChannel);
        }
        assert mNotificationManager != null;

        mNotificationManager.notify(1, mBuilder.build());


    }


回答5:

I would suggest using getData() instead of getNotification(). In getData() the notification is received & shown regardless if the app is in foreground/background. Here is the docs for further reference : FCM