Support Topics Documentation Slack YouTube Blog

Obtaining custom notification header in Android

Issue is fixed and will be published to maven central with a new version of Android SDK during next week

Anton

1 Like

Hi @milen-marinov

Fix for this scenario is now available in version 5.3.0 of Android SDK, please verify. Apologies for the inconveniences it may have caused.

Anton

Hi @anton-govorushkin,

Thanks for the update! Unfortunately, the problem still persists in SDK v5.3.0. You can check again with my project and the same scenario - just update the backendless dependency to the new version.

Best,
Milen

Hi, @milen-marinov

I checked the same scenario with your project and backendless version 5.3.0 and it works fine for me. I follow the next steps:

  1. Update backendless version to 5.3.0
  2. Add log to initFragment() method of SignalsMapActivity
  3. Run the app
  4. Send push through SDK with signalId value = 1
  5. Send another push through SDK with signalId value = 2
  6. Open first notification and receive the signalId header value “1”
  7. Open the second notification and receive the signalId header value “2”

SignalsMapActivity:

private void initFragment() {
    Log.i("TAG", "RESULT: " + getIntent().getStringExtra(Signal.KEY_SIGNAL_ID));
    ...
}

Notification push:

int counter = 0;
PublishOptions options = new PublishOptions();
Map<String, String> headers = new HashMap<>();
headers.put("signalId",String.valueOf(counter++));
options.setHeaders(headers);

Backendless.Messaging.publish("default", "TEST MESSAGE", options, new AsyncCallback<MessageStatus>() {
    @Override
     public void handleResponse(MessageStatus response) {
         Log.i("TAG", response.toString());
     }

    @Override
     public void handleFault(BackendlessFault fault) {
         Log.e("TAG", fault.getMessage());
     }
});

Please double-check the version of backendless library. If you use Android Studio, run File -> Sync Project with Gradle Files.

Best regards,
Maksym

Hi @Maksym_Khobotin,

I checked again with the setup you have specified and the behaviour of the v5.3.0 SDK is not the same as before - it’s even stranger :slight_smile: It looks like there is a buffer that keeps old notification values and in each debug session you start receiving all old values one by one until you reach the new ones. To demonstrate what I mean here is the log from 3 separate debug sessions:

*** Debug session 1
2019-07-13 17:10:33.972 3916-3916/? E/TAG: RESULT: null <— Launch without notification
2019-07-13 17:11:07.603 3916-3916/? E/TAG: RESULT: A70E4957-E6AB-3F03-FFE6-A3C886EFB600 <— Value from old notification #1
2019-07-13 17:12:24.352 3916-3916/? E/TAG: RESULT: B1B3B5E6-55E5-DCFD-FFD1-7C8657E4EE00 <— Value from old notification #2
2019-07-13 17:14:28.374 3916-3916/? E/TAG: RESULT: 4BBA5804-91BE-882C-FF3E-7EBE320C0900 <— Value from old notification #3
2019-07-13 17:16:00.482 3916-3916/? E/TAG: RESULT: e5 <— Value from new notification #1
2019-07-13 17:16:36.690 3916-3916/? E/TAG: RESULT: e6 <— Value from new notification #2
*** Debug session 2
2019-07-13 17:19:03.900 5715-5715/org.helpapaw.helpapaw E/TAG: RESULT: null <— Launch without notification
2019-07-13 17:19:39.761 5715-5715/org.helpapaw.helpapaw E/TAG: RESULT: A70E4957-E6AB-3F03-FFE6-A3C886EFB600 <— Value from old notification #1
2019-07-13 17:20:15.782 5715-5715/org.helpapaw.helpapaw E/TAG: RESULT: B1B3B5E6-55E5-DCFD-FFD1-7C8657E4EE00 <— Value from old notification #2
2019-07-13 17:20:58.939 5715-5715/org.helpapaw.helpapaw E/TAG: RESULT: 4BBA5804-91BE-882C-FF3E-7EBE320C0900 <— Value from old notification #3
2019-07-13 17:21:23.816 5715-5715/org.helpapaw.helpapaw E/TAG: RESULT: e5 <— Value from new (now old) notification #1
2019-07-13 17:21:58.509 5715-5715/org.helpapaw.helpapaw E/TAG: RESULT: e6 <— Value from new (now old) notification #2
2019-07-13 17:22:27.865 5715-5715/org.helpapaw.helpapaw E/TAG: RESULT: 1CD05027-376F-C7D4-FF29-A65541C4ED00 <— Value from new notification #1
2019-07-13 17:23:13.641 5715-5715/org.helpapaw.helpapaw E/TAG: RESULT: E7CF1D7E-9CDA-A769-FF22-90180035C400 <— Value from new notification #2
*** Debug session 3
2019-07-13 17:23:58.153 6397-6397/org.helpapaw.helpapaw E/TAG: RESULT: null <— Launch without notification
2019-07-13 17:24:48.760 6397-6397/org.helpapaw.helpapaw E/TAG: RESULT: A70E4957-E6AB-3F03-FFE6-A3C886EFB600 <— Value from old notification #1
2019-07-13 17:25:29.642 6397-6397/org.helpapaw.helpapaw E/TAG: RESULT: B1B3B5E6-55E5-DCFD-FFD1-7C8657E4EE00 <— Value from old notification #2
2019-07-13 17:34:25.022 6397-6397/org.helpapaw.helpapaw E/TAG: RESULT: 4BBA5804-91BE-882C-FF3E-7EBE320C0900 <— Value from old notification #3
2019-07-13 17:34:57.100 6397-6397/org.helpapaw.helpapaw E/TAG: RESULT: e5 <— Value from new (now old) notification #1
2019-07-13 17:35:27.488 6397-6397/org.helpapaw.helpapaw E/TAG: RESULT: e6 <— Value from new (now old) notification #2
2019-07-13 17:36:00.232 6397-6397/org.helpapaw.helpapaw E/TAG: RESULT: 1CD05027-376F-C7D4-FF29-A65541C4ED00 <— Value from new (now old) notification #1
2019-07-13 17:39:00.963 6397-6397/org.helpapaw.helpapaw E/TAG: RESULT: E7CF1D7E-9CDA-A769-FF22-90180035C400 <— Value from new (now old) notification #2
2019-07-13 17:40:58.422 6397-6397/org.helpapaw.helpapaw E/TAG: RESULT: B5DACE3F-2A05-E1AE-FF7D-AEF105BFC300 <— Value from new notification #1
2019-07-13 17:41:57.617 6397-6397/org.helpapaw.helpapaw E/TAG: RESULT: 9432CCBC-F232-EDB6-FF56-BE2542091800 <— Value from new notification #2

Let me know if you need more info to replicate this behaviour!

Best,
Milen

Hi, @milen-marinov

I cannot reproduce such behaviour. Can you please try to create a new sample project and repeat your scenario to make sure the problem is not with your project’s (HelpAPaw) logic.
If the problem is reproduced in a new project, send me the project to let us help you with this issue.

Best regards,
Maksym

Hi @Maksym_Khobotin,

Just so I know where to look - did you try to reproduce the bug with my project or with another one?

Best,
Milen

Hi, @milen-marinov

I tried to reproduce your issue with your project with no success.
I suppose that your issue may be caused by the specific logic of your application. And it would be nice if you could try to reproduce the scenario with sample project without any additional logic to confirm that problem is on our side, not your.

Also did you try to reproduce my last scenario with backendless version 5.3.0?

Best Regards,
Maksym

Hi @Maksym_Khobotin,

Yes, I am using SDK v5.3.0. Today I checked again but unfortunately the app still behaves the same way:

  1. When I first launch the app no extras are delivered
  2. When I tap to open a notification it receives the extras from the first notification that was opened since the app was installed
  3. When I tap to open another notification it receives the extras from the second notification that was opened since the app was installed
  4. This behaviour continues until all previous notification extras have been delivered yet another time. Then the app starts receiving the extras from the current notifications. If I start another session the new notification extras are added to this list.
  5. I need to delete all app data and the app itself to start clean (i.e. receive the extras from the notification that was opened) only to repeat this whole behaviour between debug sessions.

It just looks like Backendless SDK delivers the extras for the wrong notification. I will try to reproduce that behaviour in a new project when time allows it (which unfortunately will not be very soon). In the mean time I will be happy if you could test this some more as my app doesn’t store and doesn’t set intent extras so I really don’t see how it could be responsible for this!

Best Regards,
Milen

Hi, @milen-marinov

Thanks for the detailed information. I will try to reproduce it again with the steps you have described above. And let you know once I get the results.

Best Regards,
Maksym

Hi, @milen-marinov

I tried to reproduce your issue one more time - and everything works fine for me. I followed the next steps:

  1. First launch the app, no extras.
  2. Open the first-ever notification with first extras.
  3. Repeat step 2 several times, receive correct extras.
  4. Close application, force-stop it for sure and open again.
  5. Open notification and receive correct extras for it.

Also I tried to close app and open notification with closed app. Works fine.
Also I noted that when I reopen the app and click on notification, the SignalsMapActivity is not recreated and initFragment() method is not called.

Maybe it’s some side effect that is not visible at first glance.

If you have the opportunity, please provide the sample project with your issue.

Best Regards,
Maksym

Hi @Maksym_Khobotin,

Thanks a lot for checking again!
I did some more debugging and found something interesting!
I created a service that inherits from BackendlessFCMService and overrides public boolean onMessage(Context appContext, Intent msgIntent ). In that method I confirmed that the received msgIntent indeed receives the correct push notification headers. Stepping through BackendlessFCMService I verified that everything goes well up until the end of fallBackMode where the notification is sent with a PendingIntent that contains an Intent holding the correct extras. The strange thing happens after that when I open the notification. App’s main activity is launched with an Intent that contains extras from an old notification. It looks like the delivered Intent is not the same as the one that is packed in the notification’s PendingIntent. Any idea what might be the reason for such behaviour?

P.S. Just to make sure we are testing with the same environment - I’m testing on physical devices with Android 9.

Best Regards,
Milen Marinov

I think I got the answer! It looks like the Android system reuses PendingIntents but doesn’t handle well equal Intents with different extras: https://stackoverflow.com/questions/18049352/notification-created-by-intentservice-uses-always-a-wrong-intent/18049676#18049676
In a debug session I changed this line:
https://github.com/Backendless/Android-SDK/blob/271f2a559c14cfdd9c6ca979e953e95c1beef036/src/com/backendless/push/BackendlessFCMService.java#L187
from:
PendingIntent contentIntent = PendingIntent.getActivity( context, notificationId * 3, notificationIntent, 0 );
to:
PendingIntent contentIntent = PendingIntent.getActivity( context, notificationId * 3, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT );
and the problem disappeared!
If this is the case indeed it will explain the hard-to-reproduce nature of the problem since Intent reuse is probably dependent on a lot of factors (system version, free RAM, etc.)

Can you check the implications of such a change and let me know if and when you are going to do it?

Best Regards,
Milen Marinov

Hi Milen,

Thank you for the investigation and sharing your finding with us. We will definitely look into it from our side and let you know.

Regards,
Mark

1 Like

Hi @milen-marinov

Yes, you are right. The Android system reuses PendingIntents. That is why we create unique Intent each time by setting unique requestCode for it (notificationId * 3). So the system cannot reuse intents and creates new notification with new extras every time.
FLAG_UPDATE_CURRENT - is a

Flag indicating that if the described PendingIntent already exists, then keep it but replace its extra data with what is in this new Intent.
https://developer.android.com/reference/android/app/PendingIntent#FLAG_UPDATE_CURRENT

It means that if you send two notifications in a row with different extras, the extras in the notification that comes first will be replaced with a new one, from the last notification.

Here is a schema to be more clear:

  1. Notification 1 comes with extras 1.
  2. Notification 2 comes with extras 2.
  3. System detects that these two notifications has equal Intents. Because you set the flag FLAG_UPDATE_CURRENT, it modifies the second notification in the following way:

keep it but replace its extra data with what is in this new Intent.

It means that exras 1 in notification 1 will be replaced by extras 2.

  1. So now you have notification 1 with extras 2 and notification 2 with extras 2.
  2. If you click on notification 1 after this, you receive extras 2 that is not a correct behavior.

Can you please reproduce that scenario I’ve described and confirm it?

Also I will appreciate if you can check PendingIntents for equality and check if notificationIds is different for two different notifications in a debug session.

Best Regards,
Maksym

Hi @Maksym_Khobotin,

Thanks for the clarification! I now understand fully what is happening! Here are the logs from my test:

=== Debug session 1 ===
2019-08-11 15:26:25.488 10876-13125/org.helpapaw.helpapaw D/BackendlessFCMService: Bundle[{ios-category=kNotificationCategoryNewSignal, google.delivered_priority=normal, google.sent_time=1565526388424, google.ttl=2419200, google.original_priority=normal, messageId=message:F5349594-8AB8-4DEF-8774-29D7163E317E, ios-alert=Л1, ios-badge=1, ios-sound=default, from=960611584456, signalId=C882A24F-48DD-944E-FF98-0D4EA3CBC700, google.message_id=0:1565526388432993%56b7c464f9fd7ecd, message=Л1, BL_APPLICATION_ID=BDCD56B9-351A-E067-FFA4-9EA9CF2F4000}]
2019-08-11 15:28:52.842 10876-13125/org.helpapaw.helpapaw D/BackendlessFCMService: notificationId: 0
2019-08-11 15:29:56.546 10876-13125/org.helpapaw.helpapaw D/BackendlessFCMService: Bundle[{ios-category=kNotificationCategoryNewSignal, google.delivered_priority=normal, google.sent_time=1565526599324, google.ttl=2419200, google.original_priority=normal, messageId=message:EFB80473-BB97-4044-92B6-07DE6931D073, ios-alert=Л2, ios-badge=1, ios-sound=default, from=960611584456, signalId=D766E85F-DB30-2431-FFCA-052E784DC600, google.message_id=0:1565526599330682%56b7c464f9fd7ecd, message=Л2, BL_APPLICATION_ID=BDCD56B9-351A-E067-FFA4-9EA9CF2F4000}]
2019-08-11 15:29:56.860 10876-13125/org.helpapaw.helpapaw D/BackendlessFCMService: notificationId: 1
2019-08-11 15:31:13.982 10876-13125/org.helpapaw.helpapaw D/BackendlessFCMService: Bundle[{ios-category=kNotificationCategoryNewSignal, google.delivered_priority=normal, google.sent_time=1565526676845, google.ttl=2419200, google.original_priority=normal, messageId=message:56664A5E-304D-46E9-8E2E-9CEA2D5ED139, ios-alert=Л3, ios-badge=1, ios-sound=default, from=960611584456, signalId=EB0F218F-589E-19A9-FF9D-B0B35BF55B00, google.message_id=0:1565526676852475%56b7c464f9fd7ecd, message=Л3, BL_APPLICATION_ID=BDCD56B9-351A-E067-FFA4-9EA9CF2F4000}]
2019-08-11 15:31:14.288 10876-13125/org.helpapaw.helpapaw D/BackendlessFCMService: notificationId: 2
=== Debug session 2 ===
2019-08-11 15:32:42.704 13685-14095/org.helpapaw.helpapaw D/BackendlessFCMService: Bundle[{ios-category=kNotificationCategoryNewSignal, google.delivered_priority=normal, google.sent_time=1565526765602, google.ttl=2419200, google.original_priority=normal, messageId=message:23ADE9B4-B587-40E4-AA1A-968C8E93ACF7, ios-alert=Л4, ios-badge=1, ios-sound=default, from=960611584456, signalId=BDD0DB0F-4C18-E9BF-FFE4-27F6792B3000, google.message_id=0:1565526765606769%56b7c464f9fd7ecd, message=Л4, BL_APPLICATION_ID=BDCD56B9-351A-E067-FFA4-9EA9CF2F4000}]
2019-08-11 15:32:43.121 13685-14095/org.helpapaw.helpapaw D/BackendlessFCMService: notificationId: 0

As you can see notificationId is restarted in each debug session. Looking at the code:
private static AtomicInteger notificationIdGenerator;

The field is static which means its value is kept between instances of BackendlessFCMService. However, when the whole app is killed this field is destroyed, too. So, next time you start the app the counter starts again from 0. This behaviour is not limited to debugging as the app might be killed manually by the user, automatically by the system, etc. Indeed, my tests confirm that manually killing and starting the app resets the counter.
I would suggest using a different mechanism for generating unique notificationIds. As in practice the SDK never updates sent notifications (which is the reason notificationIds exist) you can use a random int or maybe base it on the notification’s timestamp.

Best Regards,
Milen Marinov

Hi, @milen-marinov

It’s very strange behaviour.
The notificationId is generated by notificationIdGenerator. And its value is saved to shared preferences each time the service stops in onDestroy method. You can look at this code here:

So even if I force-stop the application, the value of notificationId is saved and then restored from Android Shared Preferences.
I can only come up with one scenario, when the value can be resetted - if you clear the application data. In this case id counter resets and starts counting from 0.
I tried to reproduce this issue many times, but the counter didn’t reset any single time. Only if I clear the app data on my phone - it resets (but this is expected behavior in this case).

How do you restart your application? Which steps do you follow between debug sessions?
What do you mean by

manually killing and starting the app

?

Also do you test this behavior with different android versions?

I will be glad to hear your answers and to assist you further!

Best Regards,
Maksym

Hi @Maksym_Khobotin,

About your question:

In the debug scenario:

  1. Press Debug in the IDE
  2. Press Stop in the IDE
  3. Press Debug in the IDE

In the manual restart scenario:

  1. Start app from launcher
  2. Tap Task Manager key and swipe away the app
  3. Start app from launcher

I cannot easily test if onDestroy is called in the manual restart scenario. I just tested the debug one and onDestroy is not called when you press Stop. However, as this only happens when debugging, the strange behaviour is something that can be ignored (if you know about it and that it only happens during debugging).

Best Regards,
Milen Marinov

Hi @milen-marinov!

I finally reproduced your issue! It only happens on devices with Android 9. Seems like Android changed the Service logic for the new version of OS. We are now working on this issue and will let you know once it will be fixed.
Internal ticket: 19360.
Thank you a lot for pointing out this problem. We really appreciate it!

Best Regards,
Maksym

1 Like

Hi @Maksym_Khobotin,

That’s great! Thanks a lot!

Best Regards,
Milen Marinov