Get payload data from FCM Message when app is in the background - java

I try to get the payload data from a fcm message, while my app is in the background. So I read this documentation and they say,
I can get the data in the extras of the intent from my launcher activity, because if you click on the notification by default your launcher activity will open.
I send the message via the firebase console, then my app is in the foreground, I can handle all this via the onMessageReceived() method.
This is my code to achieve this, but the intent extras are null..
if (getIntent().getExtras() != null) {
bundleFCM = getIntent().getExtras();
for (String key : bundleFCM.keySet()) {
Log.d(TAG, "payload keys: " + key);
}
}

Okay my problem was, that I have a SplashActivity and the data payload was sent to this activity, so I transfer the data from the SplashActivity to my HomeActivity and all works fine.

Related

setting badge when Firebase Cloud Message is received in Ionic App

I'm having a hard time getting responses to my questions lately and I'm not why. If I am not asking right, can someone please let me know so I can adjust?
I am building an app with Ionic but having issues sending badge numbers for Android via FCM. I can't find anything in the Firebase Docs. How do I set the badge count when a message is received?
Here is my thought process but I don't know how to get it to work:
when the message is received, use the ionic native badge plugin to set it
send the badge count using FCM payload
NOTE: I am using NodeJS implementation for Firebase
What I've tried
I am using the cordova-plugin-fcm plugin and the Android ShortcutBadger to set the badge, but I am unable to set the badge when the message is received. I was only able to set it when the app is already open by calling the shortcutbadger function in the MyFirebaseMessagingService java class (of the cordova-plugin-fcm). Below is the code I am using in my FCMPluginActivity java class:
// more imports here
import me.leolin.shortcutbadger.ShortcutBadger;
public class FCMPluginActivity extends Activity {
private static String TAG = "FCMPlugin";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(TAG, "==> FCMPluginActivity onCreate");
Map<String, Object> data = new HashMap<String, Object>();
if (getIntent().getExtras() != null) {
Log.d(TAG, "==> USER TAPPED NOTFICATION");
data.put("wasTapped", true);
for (String key : getIntent().getExtras().keySet()) {
String value = getIntent().getExtras().getString(key);
Log.d(TAG, "\tKey: " + key + " Value: " + value);
data.put(key, value);
}
}
FCMPlugin.sendPushPayload(data);
ShortcutBadger.applyCount(FCMPluginActivity.this, 8);
finish();
forceMainActivityReload();
}
I am importing ShortcutBadger and using it in the onCreate method. The idea is to set the badger when the notification is received; however, this is not working.
Your thoughts and comments are very much appreciated
Set the badge field when you send the notification. The documentation specifies this for ios and based on my test it works, but with some delay. I would also try it for Android, but it may not be possible:
Search for 'badge' here:
https://firebase.google.com/docs/cloud-messaging/http-server-ref

Hide push notification if it contains specific elements

I won't show a received push notification from appearing top notifications menu my notification if it has for example key update. For now if I get notification with this key, all notifications are in the notification bar. I want to not present this notifications for user.
I'm using WakefulBroadcastReceiver for handle notifications like below:
public class PusherReceiver extends WakefulBroadcastReceiver {
private boolean isAppOnForeground(Context context) {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
if (appProcesses == null)
return false;
final String packageName = context.getPackageName();
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
return true;
}
}
return false;
}
public void onReceive(final Context context, Intent intent) {
Log.i("SimpleWakefulReceiver", "Starting service # " + SystemClock.elapsedRealtime());
if (!isAppOnForeground((context))) {
String pushNotificationBody = intent.getStringExtra("alert");
try {
JSONObject notificationData = new JSONObject(pushNotificationBody);
// This is the Intent to deliver to our service.
Intent service = new Intent(context, BackgroundService.class);
// Put here your data from the json as extra in in the intent
service.putExtra("notification", pushNotificationBody);
Log.i("PUSH_NOTIFICATION_JSON", "RECEIVED JSON " + notificationData);
// Start the service, keeping the device awake while it is launching.
if (!notificationData.has("update")) {
startWakefulService(context, service);
} else {
// Do nothing
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
UPDATE:
I changed project a little and with Onesignal and his NotificationExtenderService, I did something like below:
public class NotificationNotDisplayingExtender extends NotificationExtenderService {
#Override
protected boolean onNotificationProcessing(OSNotificationReceivedResult receivedResult) {
String notification = receivedResult.toString();
String notificationBody = receivedResult.payload.body;
JSONObject notificationBodyJSON = null;
try {
notificationBodyJSON = new JSONObject(notificationBody);
} catch (JSONException e) {
e.printStackTrace();
}
JSONObject pushNotificationData = notificationBodyJSON;
boolean hidden = false;
if (pushNotificationData.has("update")) {
Log.i("NOTIFICATION MANAGER", "PREVENT DISPLAY NOTIFICATION");
hidden = true;
}
// Return true to stop the notification from displaying.
return hidden;
}
}
And it prevent displaying notifications with update key, but now I don't receive it in my PusherReceiver to start my service. Is there easy way to send data from my NotificationNotDisplayingExtender receivedResult to my PusherReceiver?
For now it looks like my PusherReceiver don't fire his onReceive method.
Many thanks for help in advance.
There are two types of payload.
1. Data
2. Notification
https://developers.google.com/cloud-messaging/concept-options
Use only data payload. Then you always get the call in FirebaseMessagingService onMessageRececived Method
The thing is basically we have two type of notifications.
One which can be called Notification Type, is that the push has a notification object in sent/received bundle, in which you have to handle it when your app is in foreground and the notification is received. In this case, if your app is in foreground, then you can handle it and do whatever you like which is not showing a notification. But if the app is in background, a notification will automatically create by google and it takes predefined title and message objects within the received push bundle to make the notification.
Second type which can be called Data Type, do not have any notification object in the sent/received bundle. In this scenario, your app is in foreground or background, you should handle everything. So, if you put your data in data object of your push notification message, everything will be in your hands.
So, in short, just put your data in data object of your notification and implement your desired logic.
I do not see the JSON data you are referring to. However, I suppose the update key in your JSON is containing null. In your code you are checking if the JSON data has the key update in it. This function will always return true if the key exists in the JSON body. You might have the field with null value which is indicating that you are not supposed to show the notification in the system tray.
In that case, you might consider using isNull function. It returns true if this object has no mapping for update or if it has a mapping whose value is null.
// Start the service, keeping the device awake while it is launching.
if (!notificationData.isNull("update")) {
startWakefulService(context, service);
} else {
// Do nothing
}
And yes, please use the data payload from the notification that you get.
Every time you notify the NotificationManager to show a notification, you provide an ID to be used for the notification to edit or cancel that notification later on. If you show a notification by manager.notify(notificationId, notification), you can cancel it with manager.cancel(notificationId).
If you want to remove all the notifications, you can use NotificationManager.cancelAll().

Android notification from device 1 to 2

I am developing an app for android using eclipse, what i'm basically trying to do is:
send an notification form my device(1) to another device(2).
I am using user log in with is already configured with a database.
When I press down on user(when i press down on a button that sends the notification).
I want device 1 to send an notification that shows on device 2.
Both devices are logged in with different users, but I can't make the notification part to work.
edit: when I push the button the notification displays on device 1, but iI want it to display on device 2...
This is the code of receiving a notification:
public void NmRecv(String username, String message)
{
FriendInfo friend = FriendController.getFriendInfo(username);
MessageInfo msg = MessageController.checkMessage(username);
if ( msg != null)
{
Intent i = new Intent(TAKE_MESSAGE);
i.putExtra(MessageInfo.USERID, msg.userid);
i.putExtra(MessageInfo.MESSAGETEXT, msg.messagetext);
sendBroadcast(i);
String activeFriend = FriendController.getActiveFriend();
if (activeFriend == null || activeFriend.equals(username) == false)
{
localstoragehandler.insert(username,this.getUsername(), message.toString());
showNotification(username, message);
}
}
}
any ideas?
You can achieve that using Google Cloud Messaging.
Also check this link.
You'll have to register the Android devices' keys in order to be able to send notifications.
In other words. You need to store the devices' keys in the Database when they log in.
And then when device1 wants to send a notification to device 2 you do that using GCM and the device 2 key that's stored in the database.
Here's an example of the code I'm using server side to send a message using GCM:
Sender sender = new Sender (SENDER_API_CODE);
Message message = new Message.Builder ()
.collapseKey ("1")
.timeToLive (2419200)
.delayWhileIdle (false)
.addData ("message", "example message")
.build ();
result = sender.send (message, reGid, sendCount);
Receiving side you have to create a Broadcast Receiver with these actions:
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<action android:name="com.google.android.c2dm.intent.GCM_RECEIVED_ACTION" />
and then when you receive the intent you get the message like this:
Bundle extras = intent.getExtras();
GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
String messageType = gcm.getMessageType(intent);
if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType))
{
//Here you process the intent like you normally would
//String parameter = intent.getStringExtra("name of parameter");
//...
//After that you can create a notification like in the link below.
}
creating notifications

how to delete GCMRegistered device id from database if user Uninstall application

public class GCMIntentService extends GCMBaseIntentService {
NotificationManager mNotificationManager;
Context cc;
#Override
protected void onRegistered(Context context, String regId) {
Intent intent = new Intent(Constants1.ACTION_ON_REGISTERED);
intent.putExtra(Constants1.FIELD_REGISTRATION_ID, regId);
context.sendBroadcast(intent);
}
#Override
protected void onUnregistered(Context context, String regId) {
Log.i(Constants1.TAG, "onUnregistered: " + regId);
AlertDialog.Builder alert = new AlertDialog.Builder(
getApplicationContext());
alert.show();
}
#Override
protected void onMessage(Context context, Intent intent) {
/**
* You can get the Extras from TaxMann server
*
* Bundle _bundle = intent.getExtras();
*/
String msg = intent.getStringExtra("payload");
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
BackgroundAlert bg = new BackgroundAlert(mNotificationManager, msg);
bg.onReceive(getApplicationContext(), intent);
}
#Override
protected void onError(Context context, String errorId) {
}
}
This is my code for gcm i have approx 15000 registered_device_id in my database for notification when i send notification to all register device id then it show 10000 success and 6000 unsuccessful .i want to delete all 6000 registered device id from our database so that it take less time to get notification .
You need not to do anything in android code. GCM is smart enough to handle it. So, once our app is uninstalled, GCM will take care of removing that Registration ID from GCM. However, we have to delete that registration Id from our server database, once we get the response from GCM as "NotRegistered", we have to remove that particular registration ID from our database.
Following are the sequence of events.
The end user uninstalls the application.
The 3rd-party server sends a message to GCM server.
The GCM server sends the message to the device.
The GCM client receives the message and queries Package Manager about whether there are broadcast receivers configured to receive it,
which returns false.
The GCM client informs the GCM server that the application was uninstalled.
The GCM server marks the registration ID for deletion.
The 3rd-party server sends a message to GCM.
The GCM returns a NotRegistered error message to the 3rd-party server.Once, we receive this kinda response from GCM, we have to
delete that particular registration ID from our database.
Follow that link might be use full for you
Google Cloud Messaging registration id expiration

How to suppress new SMS notification?

I'm writing my own SMS messenger and I need to completely suppress new SMS notification raised by default stock messenger. For sure I'm intercepting incoming SMS notification and aborting Broadcast through BroadcastReceiver.abortBroadcast(), like:
public void onReceive(Context context, Intent intent) {
Map<String, String> msgs = retrieveMessages(intent);
for (String address : msgs.keySet()) {
String msg = msgs.get(address);
Log.i(TAG, "New sms received=" + msg);
//saving message in phone
Message message = Message.createIncomingMessage(address, msg);
message.setSeen(1); ////mark message seen, so stock messenger couldn't arose notification
message.setRead(1); //mark message read, so stock messenger couldn't report it as unread
message.setUnread(true); //mark message unread for our messenger
message = Me.getMe().getMessageDAO().save(context, message); //saving message
SmsReceiver.updateNotification(context, message, true, true); //raise notification from "our" messenger
}
//aborting default broadcast, since everything already done and no need to do more
this.abortBroadcast();
}
Everything works as planned. But whenever I'm inserting new SMS into database through Me.getMe().getMessageDAO().save(context, message); within few seconds stock messenger somehow is being notified about new message in database and again raises notification.
Question is: how to suppress this notification?
first you need to set priority of your receiver see docs.
secondly, call abortBroadCast before you do heavy processing task(storing into DB).
or you can try this db storing thing in a thread, Start the thread and call abortBroadcast() immediately.

Categories

Resources