8

I want to handle firebase notification message on background as well as on foreground . I will send a message that will consist a youtube link from developer and when user tap on notification bar it must direct user to open the link. Does anyone knows how it is done?

 public void onMessageReceived(RemoteMessage remoteMessage) {
    // [START_EXCLUDE]
    // There are two types of messages data messages and notification messages. Data messages are handled
    // here in onMessageReceived whether the app is in the foreground or background. Data messages are the type
    // traditionally used with GCM. Notification messages are only received here in onMessageReceived when the app
    // is in the foreground. When the app is in the background an automatically generated notification is displayed.
    // When the user taps on the notification they are returned to the app. Messages containing both notification
    // and data payloads are treated as notification messages. The Firebase console always sends notification

    // [END_EXCLUDE]

    // TODO(developer): Handle FCM messages here.
    // Not getting messages here? See why this may be:
    Log.d(TAG, "From: " + remoteMessage.getFrom());

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

    // Check if message contains a notification payload.
    if (remoteMessage.getNotification() != null) {
        Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
    }

    // Also if you intend on generating your own notifications as a result of a received FCM
    // message, here is where that should be initiated. See sendNotification method below.
}

what to do next to achieve my goal? Thanks in advance:)

AL.
  • 36,815
  • 10
  • 142
  • 281
vishal gupta
  • 377
  • 2
  • 5
  • 17
  • The code posted is just the one from the samples. So I'm presuming you've gone through them. Was there anything confusing about it? Have you also gone through the docs? Right now, this is just like a *give me code* question. – AL. Mar 16 '17 at 09:06
  • Try My solution?
    I've already tried it.
    And it works
    https://stackoverflow.com/questions/48897883/how-to-handle-notifications-with-fcm-when-app-is-in-either-foreground-or-backgro/48899186#48899186
    – Leon Chang Feb 21 '18 at 07:02

7 Answers7

5

You should send data payload in your FCM message. Data payload gets received in on message method irrespective of your app being in foreground or background. Handle the action there. Like show notification by reading the data payload always, or if you want show an alert dialog when your app is open or in the foreground.

here is a sample payload:

{
  "to": "registration_id_or_topic",
  "data": {
        "message": "This is a Firebase Cloud Messaging Topic Message!",
        "youtubeURL": "https://youtu.be/A1SDBIViRtE"
   }
}

Then in your onMessageReceived:

public void onMessageReceived(RemoteMessage remoteMessage) {
   if (remoteMessage.getData().size() > 0) {
        Log.d(TAG, "Message data payload: " + remoteMessage.getData());
        Map<String, String> receivedMap = remoteMessage.getData();
        String youtubeURL = receivedMap.get("youtubeURL");
        showNotificationWithURLAction(youtubeURL);
   }
   .....
}

you can easily implement showNotificationWithURLAction(...) method by googling it out. One sample is here

Community
  • 1
  • 1
drulabs
  • 3,071
  • 28
  • 35
4

This is a possible duplicate of this question. Don't send a "notification" in your push message body.

So basically, I changed the body for the push notification request from:

{
   "data": {
       "type" : "mytype"
    },
    "notification": {
        "title": "My Title",
        "body": "My Notification Message"
    },
    "to": "/topics/all"
}

To:

{
   "data": {
       "type" : "mytype",
       "title": "My Title",
       "body": "My Notification Message"
    },
    "to": "/topics/all"
}

Now my app calls onMessageReceived() everytime even in background, and I just changed the methods to use the obtained notification title and message in the push data.

Community
  • 1
  • 1
Alvin Rusli
  • 1,026
  • 1
  • 11
  • 19
  • Hi, my app not call onMessageReceived() in background. – Avinash May 24 '17 at 07:01
  • Thank you ! This is the most important and acceptable message. I ve been struggling non-stop from 8 hours and finally ! as you said .. it is working in both cases – Emre Kilinc Arslan Mar 15 '18 at 23:16
  • Alvin, what do you mean by app in background , we should get notification when app is killed also not only in Background or Foreground. – Sagar Panwala Jul 25 '18 at 03:35
  • @SagarPanwala By background, I mean when the app isn't currently visible to the user – Alvin Rusli Jul 26 '18 at 04:56
  • Exactly Alvin, but we all need to get notifications when app is killed – Sagar Panwala Jul 26 '18 at 05:27
  • @SagarPanwala Your app should still receive the push messages even if it's killed, I don't understand the problem here – Alvin Rusli Jul 26 '18 at 06:21
  • There are many devices which are not receiving notifications when app killed, like Xiomi, Oppo, Vivo, some Samsung device, Lenovo and HTC. If we turned off battery optimization then only we receive notification – Sagar Panwala Jul 26 '18 at 06:29
  • @SagarPanwala That's more of a device settings, we can't really do much there if the device owner wants to kill your app's background services. Even my phone (Asus Zenfone 3) doesn't get Whatsapp notifications reliably. – Alvin Rusli Jul 26 '18 at 09:44
2

When your app kill or background never trigger onMessageReceive

What should do you?

When push send only add Data items below example; You can use postman

Firstly need this url : https://fcm.googleapis.com/fcm/send When you send you can choose POST

After you should add Headers like that:

Content-Type: application/json

Authorization: key="your server key"

  {
        "to": "/topics/yourTopics",


        "data": {
            "title": "BlaBla",
            "body":"BlaBla"
         }
    }

How to Handling;

class PushService : FirebaseMessagingService() {

     override fun onMessageReceived(remoteMessage: RemoteMessage?) {
    for (i in remoteMessage!!.data.keys) {
    //Your maps here you can do something..
    }


        val contentIntent = PendingIntent.getActivity(this,
                0, intent, PendingIntent.FLAG_UPDATE_CURRENT)

        val uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)
// Your notification set here!! 
        val b = NotificationCompat.Builder(this, "1")
        val n = b.setTicker(remoteMessage!!.data["title"])
                .setWhen(0)
                .setAutoCancel(true)
                .setContentTitle(remoteMessage.data["title"])
                .setContentText(remoteMessage.data["body"])
                .setShowWhen(true)
                .setContentIntent(contentIntent)
                .setSound(uri)
                .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
                .setLargeIcon(BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher))
                .setStyle(NotificationCompat.BigTextStyle().bigText(remoteMessage.data["body"]))


        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            b.setSmallIcon(R.drawable.ic_push_notification_transparent)
            b.color = ContextCompat.getColor(this, R.color.colorAccent)
        } else {
            b.setSmallIcon(R.mipmap.ic_launcher)
        }

        val notificationManager = this.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel("1",
                    "ic_notification",
                    NotificationManager.IMPORTANCE_DEFAULT)
            notificationManager.createNotificationChannel(channel)
        }

        if (notificationManager != null) {
            notificationManager.cancel(1)
            notificationManager.notify(1, n.build())
        }
    }


}
Deniz
  • 319
  • 5
  • 9
0

If you want to redirect user to content in your app than use deepLink, here is how to just open link when notification is clicked:

Intent notificationIntent = new Intent(Intent.ACTION_VIEW);
        notificationIntent.setData(Uri.parse(remoteMessage.getData().getString("url")); 
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
         // Resources r = getResources();
          Notification notification = new NotificationCompat.Builder(context)
                  .setTicker("yortext")
                  .setSmallIcon(android.R.drawable.ic_menu_report_image)
                  .setContentTitle("title")
                  .setContentText("content")
                  .setContentIntent(pendingIntent)
                  .build();

          NotificationManager notificationManager =  (NotificationManager) context.getSystemService(Service.NOTIFICATION_SERVICE);
          notificationManager.notify(0, notification);

To send payload go into firebase console, create new message, here you will have advanced options, where you can put your data in key/value pairs, put url as on photo below.

Adding payload to Firebase message

Drake29a
  • 896
  • 8
  • 23
0

The android system will always handle messages inside the notification field in the payload. If you want your app to handle the notification, you need to put your YouTube link inside that data field in your payload.

{ "data" : 
    { "link" : "www.youtube.com"}
}

This notification is received on the app as a RemoteMessage. Use remoteMessage.getData() to get you youtube link.

See https://firebase.google.com/docs/cloud-messaging/concept-options#messages-with-both-notification-and-data-payloads

0

This is a working example written in nodejs for all types of condition handling Foreground, BackGround, APP Killed this will work in all three types

let message = {
        "data": {
            "callerName": "callerName",
            "notifyType": "notifyType",
            "channelName": "channelName",
            "tragetuid": "tragetuid",
            "msg": "msg"
        },

        token: "cq4KgPelQ_ukmAL1NmNs0l:APA91bG0l2uS1djSsD181cgtgFSd8......",
    };

    let response = await admin.messaging().send(message).catch((error) => {
        console.log('Error sending message:', error);
    });
    if (!response) {
        ctx.status = 404;
        ctx.body = "Error";
    } else {
        ctx.status = 200;
        ctx.body = {
            response, message
        };
    }

So basically we need to use type data instead of notification to get FCM message in OnReceived() fucntion

{
        "data": {
            "callerName": "callerName",
            "notifyType": "notifyType",
            "channelName": "channelName",
            "tragetuid": "tragetuid",
            "msg": "msg"
        },

        token: "cq4KgPelQ_ukmAL1NmNs0l:APA91bG0l2uS1djSsD181cgtgFSd8......",
    }
Ali Raza
  • 174
  • 1
  • 3
0

You need to set click_action in firebase notification data set to be able to receive data from background and handle foreground data in onMessageReived.

See updated answer here: https://stackoverflow.com/a/73724040/7904082

Akinyemi Jamiu
  • 431
  • 3
  • 10