16

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?

KENdi
  • 7,576
  • 2
  • 16
  • 31
ziniestro
  • 686
  • 1
  • 11
  • 24

5 Answers5

13

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

Gundu Bandgar
  • 2,593
  • 1
  • 17
  • 21
1

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.

ziniestro
  • 686
  • 1
  • 11
  • 24
0

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

Arnav Rao
  • 6,692
  • 2
  • 34
  • 31
  • Hi Arnav, yes when I debug it I can see notification and data, I don't think that I need a background thread to open the notification... should be simpler right? Thanks for replaying – ziniestro Feb 22 '18 at 04:57
  • You are saying you don't need background thread because it is simple and not exceeding the time limit right. Just try and see whether it works. And also tell me where exactly is the failure point in the service. What is the last statement you see being executed when you debug it. – Arnav Rao Feb 22 '18 at 05:11
  • if you see my code is going through onMessageReceived and then parsing all of the data (correctly) to finally call sendNotification(title, message, launchPage) and that pice of code is been executed as well but I'm not seeing the notification. – ziniestro Feb 22 '18 at 05:18
0
@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());


    }
MEGHA DOBARIYA
  • 1,622
  • 9
  • 7
-1

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

supro_96
  • 570
  • 6
  • 14
  • Hi @Supradip.M I'm using remoteMessage.getData(), it's in my code – ziniestro Feb 22 '18 at 04:10
  • Are you sending data payload?? If data is not sent nothing will be shown. – supro_96 Feb 22 '18 at 04:21
  • yes.... If I close the app, I can see the notification coming and when I click on it the app handles it showing the page sent in the payload. If I debug the app and it's open I can see the payload as well, but is not showing the notification for some reason. I've check the settings and the notifications are enabled. Thanks for replaying – ziniestro Feb 22 '18 at 04:24
  • Please post the code of uploading data. Then we can see what exactly is happening. – supro_96 Feb 22 '18 at 04:26
  • yes If I inspect remoteMessage.getData() I'm seeing {ArrayMap} size = 2; value[0] = "123456", value[1]="detailPage" – ziniestro Feb 22 '18 at 04:35
  • Try using only getData() and check if it solves the problem – supro_96 Feb 22 '18 at 04:52
  • getData() rather remoteMessage.getData()... if it's that the method doesn't exist..... – ziniestro Feb 22 '18 at 05:00
  • Well, it's like this -> remoteMessage.getData().get("data_Name"); You'll have to pass JSONArray [In FCM Docs] containing data field. It works without any issue. Background/Foreground. Take out the remoteMessage.getNotification() and try it. Data Fields are what saved me from this error. Pleas update once you get the answer. – supro_96 Feb 22 '18 at 05:06
  • yes... it's what I'm doing if you check my code... remoteMessage.getData().get(Consts.LAUNCH_PAGE) – ziniestro Feb 22 '18 at 05:19
  • to force the app to read the data in onMessageReceived(), use a datapayload, but that doesn't mean parsing the notification -after that- will affect the outcome – SoliQuiD Feb 14 '19 at 09:55