0

I want to execute some code when my android device receives a push notification. I have the following files: MainActivity.java, MyFirebaseMessagingService.java.
In MainActivity, I start the messaging service:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    startService(new Intent(this, MyFirebaseMessagingService.class));
}

and in MyFirebaseMessagingService, I override the onMessageReceived method as follows:

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG = MyFirebaseMessagingService.class.getName();

    public MyFirebaseMessagingService() {
        super();
        Log.d(TAG, "init");

    }

    @Override
    public void onNewToken(String token) {
        Log.d(TAG, "app-token: " + token);
    }

    @Override
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.d(TAG, "on-message-received");
    }

Also, in my AndroidManifest, I have the following setup inside <application>:

<service
    android:name=".MyFirebaseMessagingService"
    android:stopWithTask="false"
    android:enabled="true"
    android:exported="true">
    <intent-filter>
        <action android:name="com.google.firebase.MESSAGING_EVENT" />
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <action android:name=".MyFirebaseMessagingService" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</service>

I then fire the notification, which appears on my device (it vibrates and I see the notification's title):

curl https://fcm.googleapis.com/fcm/send \                  
  -H "Authorization:key=<my-key>" \
  -H "Content-Type:application/json" \
  -d '{
    "to" : "<device token>",
    "notification": {
      "title": "hello from the server"
    },
    // or:
    "data": {
      "title": "hello from the server"
    },
    "priority": "high"
  }'

However, my code inside onMessageReceived is never executed.
I noticed that the log in onNewToken is also not called, so I'm assuming that the whole class is being ignored entirely.
The log inside MyFirebaseMessagingService's init method is called, so I know the class is registered. Just onMessageReceived isn't called – neither in fore-, nor in background; tried with both "data" and "notification" payloads.

I did a lot of research and there are tons of similar questions, but all fixes I found, like regarding the manifest, or the gradle configurations did not help me.

What am I doing wrong?
[Disclaimer: I'm an absolute beginner to Android development.]

LinusGeffarth
  • 27,197
  • 29
  • 120
  • 174
  • What does your message payload look like? Also you dont call start service on `MyFirebaseMessagingService` – tyczj Mar 10 '21 at 15:09
  • Updated my post with the payload @tyczj. How would I start the service? As far as I understood it, [the SDK starts it automatically](https://stackoverflow.com/a/43131488/3397217). – LinusGeffarth Mar 10 '21 at 15:19
  • Since in your Android Manifest you have set `android:exported="true"`,refer this [link](https://stackoverflow.com/a/49662026/11560232).This might help you. – Padmini S Mar 11 '21 at 10:27
  • Thanks. The answer you linked describes my issue, but with either `exported="true"` and `exported="false"`, my `onMessageReceived` isn't called. @PadminiS – LinusGeffarth Mar 11 '21 at 11:15

3 Answers3

0

If you look at the docs you will see that onMessageReceived is only called when you are in the foreground without data in your payload, you are only using notification in your payload.

As for starting the service you dont, Google Play Services handles the sending of notifications because of the intent filter <action android:name="com.google.firebase.MESSAGING_EVENT" />. Read the Setup docs

tyczj
  • 71,600
  • 54
  • 194
  • 296
  • I tried with a payload in which I had `data` instead of `notification`, but then I didn't receive any notification, neither in foreground, nor in background. – LinusGeffarth Mar 10 '21 at 15:30
  • when you use data you have to create the notification yourself using notification manager – tyczj Mar 10 '21 at 15:33
  • Actually that's not correct. I did get something: `D/MessagingService: Received from FCM: com.google.firebase.messaging.RemoteMessage@12c3e3e` but title is `null`. – LinusGeffarth Mar 10 '21 at 15:33
  • so I do get something when in the background, but the title & body are null. The payload is `{ "to": "...", "data": { "title": "hello, world" } }`. I don't want to show the notification to the user, I just need to get the content from that notification and do something with it. – LinusGeffarth Mar 10 '21 at 15:49
  • I dont know if you can use data and notification I have never tried that way but it sounds like you dont want notification anyway. Data is just a Key/Value pair so put what you need in there and pull the data out that way – tyczj Mar 10 '21 at 15:56
  • Right, but *how do I access the data?* That's the whole problem I'm having. I don't know how to get the payload as `onMessageReceived` is just not called. – LinusGeffarth Mar 10 '21 at 15:57
  • You just said it was getting called. Just look at the example I linked you `remoteMessage.getData()` – tyczj Mar 10 '21 at 15:57
  • Maybe I don't get you correctly. I know I need to do `remoteMessage.getData()`, but I need `remoteMessage` for that, which I *would* get from `onMessageReceived`, but I don't, since it's not called. So where do you want me to do `remoteMessage.getData()`? – LinusGeffarth Mar 10 '21 at 16:00
  • Got it but I thought you just said it was getting called a few messages ago when using data in your payload – tyczj Mar 10 '21 at 16:02
  • No. The console shows that there's *something* received, but not through system logs, not mine. – LinusGeffarth Mar 10 '21 at 16:03
  • Then its probably a configuration issue, remove all those other intent filters for your service as you dont need them and just make the service just as found in here https://firebase.google.com/docs/cloud-messaging/android/receive#edit-the-app-manifest – tyczj Mar 10 '21 at 16:11
  • Small update: I added `public MyFirebaseMessagingService() { super(); }` and logs in that method *are* logged. Hence, the class is registered fine. **But:** neither in fore-, nor background, `onMessageReceived` is called; tried with both `data` and `notification` payloads. – LinusGeffarth Mar 10 '21 at 17:13
0

onMessageReceived will only be called in this case if you are sending the the data in both notification and data objects. And that is why on foreground this class gets called, but not on background or kill state and that is why you are unable to show the desired notification. This happens because when the data in notification payload is received, the system handles this and that is why this class is never called. I will suggest you to just send all your data in data payload only and remove notification payload. I too was stuck in this issue but with close assessment i finally figured. And this will resolve all issues in all states.

Hascher
  • 486
  • 1
  • 3
  • 12
  • Thanks for your answer. Like I've written in my post, `onMessageReceived` is NOT called in the foreground either. It's just NEVER called. And my post also says that I've tried with both "notification" and "data" payload but see no difference. – LinusGeffarth Mar 11 '21 at 08:13
0

I finally found the solution to the issue. It's sort of an edge case, but might be useful for someone in the future.

The issue

When I started to implement the push notifications, I was looking into 3rd party services, in this case Pusher's Beams and added that to my gradle configuration.
I'm assuming that the pusher package tried to handle the incoming notification for me, thus my custom class' method wasn't called.

Removing the unused package from gradle & then rebuilding the project fixed the issue for me.

LinusGeffarth
  • 27,197
  • 29
  • 120
  • 174
  • Im having the same problem, but I'm currently using pusher. `onMessageReceived` doesn't get called at all, it doesn't matter if the app is on foreground, background or if the process is dead. And I am sending the payload just with `data` – FabioR Mar 01 '23 at 19:28