I am using pyFCM on a remote server to push event notifications to my app. The notification has a data payload as well, and this is needed for making some UI changes.
When the server app sends the app a notification, there is a notification that pops up on the phone, pressing which causes the default activity to be opened. Also, I have overridden the onMessageReceived in the service extending FirebaseMessagingService, and the data payload is then taken from the message and processed.
I have seen multiple questions on SO like these:
One thing in common with all the above SO questions is that they involve building a notification using Notification.Builder , and then setting up an Activity to open ( or it's onNewIntent to be triggered depending on whether it's android:launchMode is "singleTop" in the Manifest ) . My distinct understanding is that this would work if FCM were used to send the app a data message and not a notification.
The question(s)
What I really fail to understand is how setting up a notification after the data is received from FCM helps me change the behaviour of the notification received from FCM's push. Is that even possible, or have I gotten something wrong?
The second part to this question is: How do I handle a user click on a push notification to load a specific fragment in my activity (when I am not the one creating the fragment in the app - just received via FCM)?
This is the current code that runs in my app.
The onMessageReceived code is :
@Override
public void onMessageReceived(RemoteMessage remoteMessagenew) {
this.remoteMessage = remoteMessagenew;
super.onMessageReceived (remoteMessage);
database = MyDatabase.getDatabase(getApplication());
appuser = database.AppDao().getUserDetails();
Log.d(TAG, "onMessageReceived: ");
Log.d (TAG, "onMessageReceived: #########################################################");
Log.d (TAG, "onMessageReceived: #########################################################");
Log.d (TAG, "onMessageReceived: Message Data is : " + remoteMessage.getData ());
Map messageData = remoteMessage.getData ();
// Broadcast
args = new Bundle ();
int stage = 0 ;
Log.d (TAG, "onMessageReceived: ");
if(messageData.containsKey ("otherid")) {
incidenthandler(messageData);
} else if(messageData.containsKey ("itemid")) {
itemhandler(messageData);
}
}
The item handler to handle the data to refresh on the app screen
private void itemhandler(Map messageData) {
messagebody = remoteMessage.getNotification().getBody();
if(messageData.containsKey("itemid")) {
Log.d(TAG, "itemhandler: #######################");
Log.d(TAG, "itemhandler: #######################");
Log.d(TAG, "itemhandler: UPDATING");
Log.d(TAG, "itemhandler: #######################");
Log.d(TAG, "itemhandler: #######################");
String item = (String ) messageData.get("itemid");
JsonParser jsonParser = new JsonParser();
JsonObject jsonObject = (JsonObject)jsonParser.parse(item);
item refreshedItem = parseFromJson(jsonObject);
database.revivDao().upsert(refreshedItem);
} else {
// this really shouldn't happen, but putting in a scenario where this does
// syncing the db with the app
Log.d(TAG, "itemhandler: #######################");
Log.d(TAG, "itemhandler: #######################");
Log.d(TAG, "itemhandler: REFRESHING ");
Log.d(TAG, "itemhandler: #######################");
Log.d(TAG, "itemhandler: #######################");
// this triggers a call to my intentservice to refresh the db
Log.d(TAG, "itemhandler: refreshing items");
Intent intent = new Intent ("refreshitems");
Bundle clickdata = new Bundle();
data.putString("item_sub1", item_sub1);
data.putString("item_sub1", item_sub1);
intent.putExtra("data", clickdata) ; // add Bundle to Intent
localBroadcastManager.getInstance(getApplication()).sendBroadcast(intent); // Broadcast Intent
}
String itemid = messageData.get("itemid").toString();
try{
Log.d(TAG, "itemhandler: #######################");
Log.d(TAG, "itemhandler: #######################");
Log.d(TAG, "itemhandler: sending localbroadcast");
Log.d(TAG, "itemhandler: #######################");
Log.d(TAG, "itemhandler: #######################");
// this is where I try and switch to the screen to display some info - if the app is running
Intent notificationIntent = new Intent("switchtofragment");
notificationIntent.putExtra("launchitemfragment", true);
notificationIntent.putExtra("itemid", itemid);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
if(localBroadcastManager == null) localBroadcastManager = LocalBroadcastManager.getInstance(getApplication());
localBroadcastManager.sendBroadcast(notificationIntent);
// now override the notification to load the fragment on click
setupNotification(itemid, messagebody);
notificationManager.notify(1, builder.build());
} catch (NullPointerException e){
return;
}
}
Finally, the function to handle the notification:
private void setupNotification(String housecallid, String message) {
//Log.d(TAG, "setting up notification");
String idChannel = ANDROID_CHANNEL_ID;
Context context = getApplicationContext();
Intent notificationIntent = new Intent(getApplicationContext(), Reviv.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
notificationIntent.putExtra("housecallid", housecallid);
notificationIntent.putExtra("launchhousecallfragment", true);
Bundle extras = new Bundle();
extras.putBoolean("launchhousecallfragment", true);
extras.putString("housecallid", housecallid);
notificationIntent.putExtras(extras);
notificationIntent.putExtra("data", extras);
PendingIntent pendingIntent = PendingIntent.getActivity(this,0, notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
if(notificationManager == null )
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
builder = new NotificationCompat.Builder(context, null);
builder. setSmallIcon(R.drawable.heart)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(),
R.drawable.heart))
.setContentIntent(pendingIntent)
.setContentTitle("Reviv")
.setContentText(message);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if(notificationChannel == null) {
notificationChannel = new NotificationChannel(idChannel, context.getString(R.string.app_name), importance);
// Configure the notification channel.
notificationChannel.setDescription("Reviv Housecall Notification");
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
notificationManager.createNotificationChannel(notificationChannel);
builder.setChannelId(idChannel);
builder.setAutoCancel(true);
}
} else {
builder.setContentTitle(context.getString(R.string.app_name))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setColor(ContextCompat.getColor(context, R.color.transparent))
.setVibrate(new long[]{100, 250})
.setLights(Color.RED, 500, 5000)
.setAutoCancel(true);
}
builder.setContentIntent(pendingIntent);
}
Reviv
activity and replace fragments accordingly. getIntent().getExtras()
) which you are sending with the push notification in the activity which is opened by default on clicking the push notification.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.