Onmessagesent Of Firebasemessagingservice Is Not Called Accordingly
Solution 1:
Yes, is possible to send a Firebase messaging push notification and receive it in all app life cycles using onMessageReceived
.
But is necessary to change the default Firebase behaviour, intercepting the intent request before everything else.
** IMPORTANT NOTE **
This was a pretty stupid idea from Firebase by remove the developers processment capability when the FCM message arives with the notification message
format, but not for data message
.
This created a bunch of "workarounds" in many solutions, which made the analythics and everything else being messed up.
If I had designed this solution, I would always call the onMessageReceived
method with a completion handle
. Let the developer decide what to do (free tip for you, Firebase).
Use onMessageReceived
is the correct way to do. This method is the only one who brings RemoteMessage
object, that have every information what you need. It was designed for it. You are on correct path.
** HOW TO DO **
In your Firebase Class MyAndroidFirebaseMsgService
, which extends FirebaseMessagingService
, override the public method handleIntent
to intercep the intent request before Firebase catch it.
@OverridepublicvoidhandleIntent(Intent intent){
if(intent.hasExtra("google.message_id")){
intent = handleFirebaseIntent(intent);
}
super.handleIntent(intent);
}
After, transform the notification message
package into an data message
, removing all "gcm.notification.%"
and "gcm.n.%"
extras from intent, and translating "gcm.notification.title"
, "gcm.notification.body"
and "gcm.notification.image"
elements into what you need:
// Thank you Google, for that brilliant idea to treat notification message and notification data// differently on Android, depending of what app life cycle is. Because of that, all the developers// are doing "workarounds", using data to send push notifications, and that's not what you planned for.// Let the developers decide what to do on their apps and ALWAYS deliver the notification// to "onMessageReceived" method. Its simple, is freedom and its what the creative ones need.privateIntenthandleFirebaseIntent(Intent intent){
//printIntentExtras(intent);StringFCM_TITLE_KEY = "gcm.notification.title";
StringFCM_BODY_KEY = "gcm.notification.body";
StringFCM_IMAGE_KEY = "gcm.notification.image";
String title = intent.getStringExtra(FCM_TITLE_KEY);
String body = intent.getStringExtra(FCM_BODY_KEY);
String image = intent.getStringExtra(FCM_IMAGE_KEY);
// Remove the key extras that identifies an Notification type messageBundle bundle = intent.getExtras();
if (bundle != null) {
for (String key : bundle.keySet()) {
if (key.startsWith("gcm.notification.") || key.startsWith("gcm.n."))
{
intent.removeExtra(key);
}
}
}
Boolean isTitleEmpty = StringUtils.isNullOrEmpty(title);
Boolean isBodyEmpty = StringUtils.isNullOrEmpty(body);
Boolean isImageEmpty = StringUtils.isNullOrEmpty(image);
// Notification title and body has prevalence over Data title and bodyif(
!isTitleEmpty || !isBodyEmpty || !isImageEmpty
){
// This is my personalized translation method, designed for my solution.// Probably you gonna need to do it by your ownString contentData = intent.getStringExtra(Definitions.PUSH_NOTIFICATION_CONTENT);
Map<String, Object> content;
if(StringUtils.isNullOrEmpty(contentData)){
content = newHashMap<String, Object>();
content.put(Definitions.NOTIFICATION_ID, newRandom().nextInt(65536) - 32768);
content.put(Definitions.NOTIFICATION_CHANNEL_KEY, "basic_channel" );
} else {
content = JsonUtils.fromJson(newTypeToken<Map<String, Object>>(){}.getType(),contentData);
}
if(!isTitleEmpty) content.put(Definitions.NOTIFICATION_TITLE, title);
if(!isBodyEmpty) content.put(Definitions.NOTIFICATION_BODY, body);
if(!isImageEmpty){
content.put(Definitions.NOTIFICATION_BIG_PICTURE, image);
content.put(Definitions.NOTIFICATION_LAYOUT, NotificationLayout.BigPicture.toString());
}
contentData = JsonUtils.toJson(content);
intent.putExtra(Definitions.PUSH_NOTIFICATION_CONTENT, contentData);
}
//printIntentExtras(intent);return intent;
}
privatevoidprintIntentExtras(Intent intent){
Bundle bundle;
if ((bundle = intent.getExtras()) != null) {
for (String key : bundle.keySet()) {
System.out.println(key + " : " + (bundle.get(key) != null ? bundle.get(key) : "NULL"));
}
}
}
You can check my entire solution here.
Post a Comment for "Onmessagesent Of Firebasemessagingservice Is Not Called Accordingly"