6

I'm trying to send some data to my users via the new Firebase push notifications service.

I'm adding some "key-value" custom data items with 'Message text' - "dbupdate" to detect if it's an update message or a normal push notification that I want to show my users.

In my receiver I check i there is custom data and run the update, if true. If this isn't the case, I show a normal notification with the text message.

It works only when my application opened. If the application is closed, the notification is shown anyway, and my if check doesn't even running,

some code:

public class PushMessageService extends FirebaseMessagingService {
    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        super.onMessageReceived(remoteMessage);
        Map<String,String> data = remoteMessage.getData();
        String link = data.get("link");
        String name = data.get("name");
        if (link!=null) {
            Log.d("link",link);
            Log.d("name",name);
            UpdateHelper.Go(this, link, name);
        }
        else {
            NotificationCompat.Builder mBuilder =
                    new NotificationCompat.Builder(this)
                            .setSmallIcon(R.drawable.ic_shop_white_24dp)
                            .setAutoCancel(true)
                    .setContentTitle(remoteMessage.getNotification().getTitle())
                   .setContentText(remoteMessage.getNotification().getBody());
            NotificationManager mNotificationManager =
                    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            mNotificationManager.notify(5, mBuilder.build());
        }
    }
}

example notficiation here

Why is that so? What can I do to run my code even when the application closed?

Nirel
  • 1,855
  • 1
  • 15
  • 26

3 Answers3

26

As per my experience with Firebase push:

Problem: When sending push notification through "Firebase console", notification is only received when application is in foreground. If the application is killed or in background, the notification is shown only in Version >= lollipop with incorrect notification icon and/or opening the default launcher activity in the app even if you have defined different Activity in PendingIntent.

As per Firebase docs, a push message is divided into 2 pars, they call them: Docs Link here

  1. notification
  2. data payload

enter image description here

Solution:

There are two ways to send a "Push" message.

1. Firebase Console

Console

2. Messaging API - Image showing a request using Advanced REST Client

Curl Request

Push message is received in onMessageReceived(...) method. Firebase onMessageReceived(...) method will not get called if the app is in background or killed only when the message is sent through Firebase Console.

If you send the message via API, it works fine. Message is delivered in onMessageReceived(...) method whether app is in background, foreground or killed. (Caution: This is working fine in >=Lollipop - Behaviour for Android 4.4 or below is still unpredictable.

Update:

You can send a push message from API (firebase call it downstream msg) like this: https://firebase.google.com/docs/cloud-messaging/downstream

Sending downstream messages from the server

To address or "target" a downstream message, the app server sets to with the receiving client app's registration token. You can send notification messages with predefined fields, or custom data messages; see Notifications and data in the message payload for details on payload support. Examples in this page show how to send data messages in HTTP and XMPP protocols.

HTTP POST Request

https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA

{ "data": {
    "score": "5x1",
    "time": "15:10"
  },
  "to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}
Hisham Muneer
  • 8,558
  • 10
  • 54
  • 79
  • Ty for your comment, so how can i use Messaging API? There is no mention to "Messaging API" in the documentation. – Nirel Jun 15 '16 at 22:18
  • 1
    @HishamMuneer. Could you please verify that you can still send data-message to a background application via API (I mean not an apk built few weeks ago but just rebuilt after all updates), because it worked for me until recently. Unfortunately, from the exact same working project few weeks ago, I cannot get it working anymore !?! – fralbo Jul 15 '16 at 08:45
  • @2ndGAB I am using the following version and its is working perfectly fine: compile 'com.google.firebase:firebase-messaging:9.0.1'. However I am sure about future releases of firebase. – Hisham Muneer Jul 15 '16 at 16:45
  • I am getting HTTP/1.1 400 Bad Request my post is fcm.googleapis.com/fcm/send Content-Type:application/json Authorization:key=GduFdg......wK8B4Uwk2xxx... { "data": { "message": "post message", "version" : "2.0: }, "to" : "fasdsadasdsadasj9N40:APA91bGCX.....t85nX--HGg......N" } what is wrong? – Sagar Patil Oct 18 '16 at 11:21
  • This is the most authentic Answer for how to send data message from Firebase hats off – Tech Nerd May 23 '17 at 12:09
2

When you application is in the foreground, notifications will be passed to FirebaseMessagingService.onMessageReceived(). When the app is not in the foreground, the notification will be handled by the default notification center.

Also see:

Community
  • 1
  • 1
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • "data-messages: payload {"data" : { "key1" : "value1"}} These messages always invoke FirebaseMessagingService.onMessageReceived(), even if the app is closed or in background." - Diego Giorgini in your second link, so its possible, why it doesnt work? – Nirel Jun 14 '16 at 16:11
  • @Nirel, It worked until recently. I have an application built and published on 08/07/2016 which perfectly receives data messages in background. But now, I cannot make it working, even if I start from the exact same project, just rebuilt. Maybe sdk, studio, java update, I cannot say unfortunately. – fralbo Jul 15 '16 at 08:39
  • Yeah, this only work when the application in foreground. Does not work if in the background. – Norlihazmey Ghazali Jul 31 '16 at 06:23
1

In Android , if you want to update someting in the app whether the app is in forground/background/terminated states, then the best way is to remove the notification payload and send only the data payload

{ 
 "to" : "ee8....DYarin",
    "data" : {
         "key" : "value"
    }   
}

In this case onMessageReceived() will get executed. (In some android devices like xiomi you need to enable autostart for you application to process push in terminated states)

In this case, how will you show notification to user ? You can pass title and body as custom tags in the data payload and generate notification programically. So in Android everything goes well without notification payload.


And if you have notification payload in Android then the problems are:

  • If app is in forground everyting goes well, the notification is shown and onMessageReceived() is executed
  • If the app is in background/terminated states, then notification will be displayed on your device but onMessageReceived() will only work if you click on the notification. Users have the tendency to clear them often and our code in onMessageReceived() won't get executed.

Also to enable this click functionality on notification, the notification payload should contain key named click_action:

"notification":{
        "title":"Prime",
        "body" : "test",
         "click_action": "my_click_action_name"
}

And you need to register the action as intent_filter in you activity

 <intent-filter>
                <action android:name="my_click_action_name" />
                <category android:name="android.intent.category.DEFAULT" />
 </intent-filter>

When ever user clicks on notification the onNewIntent() method of the curresponding activity is called and the data payload is available in the curresponding intent.getExtras()

mustaq
  • 961
  • 14
  • 16