How get Firebase pushmessage FCM if application is down - android

I want add push cloud message in my application. I add in manifect:
<service
android:name=".firebase.MyFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
and add MyFirebaseMessagingService class and interface for it. If my application is run, I get message as RemoteMessage in my service. If application is down, push message receiver android and show notification in top part of the screen. I click this push, my application runninig and mainAcrivity have intent extras. Code in mainActivity onCreate:
if (getIntent().getExtras() != null) {
for (String key : getIntent().getExtras().keySet()) {
Object value = getIntent().getExtras().get(key);
Log.d(TAG, "Key: " + key + " Value: " + value);
}
}
Logcat output:
Key: google.delivered_priority Value: high
Key: google.sent_time Value: 1574665753356
Key: google.ttl Value: 2419200
Key: google.original_priority Value: high
Key: from Value: 69200725691
Key: google.message_id Value: 0:1574665753390474%7139185571391855
Key: collapse_key Value: ru.ittest.freezio_senser
Why I receiver no RemoteMessage? How can I get RemoteMessage use this keys?

{
"notification":{"title":"YOUR TITLE","body":"YOUR BODY"},
"to": "your device token",
"data":{
"project_type": "Remodel",
"name": "Start 45 "
}
}
Your notification response look like this . if your notification response contain this notification tag"notification":{"title":"YOUR TITLE","body":"YOUR BODY"},
then if app running then onMessageReceived method will call or if app is killed then onMessageReceived method won't call . To solve this problem you have to "notification":{"title":"YOUR TITLE","body":"YOUR BODY"}, from notification response.
And you want to open specific activity on onclick of notification.
Add this codes in activity tag in manifest
<intent-filter>
<action android:name="NotificationActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
And replace intent in Notification code in onMessageReceived
val intent = Intent("NotificationActivity")
Pass that this intent in pendingIntent
val pendingIntent = PendingIntent.getActivity(this,101,intent,PendingIntent.FLAG_UPDATE_CURRENT)

I find decide for it problem.
Thanks for Arthur Thompson: "the title body and image is not available when the user taps on the notification. If you want to get that data you will have to add it to the "data" payload of the message you are sending."
Add payload in firebase console:
Now info received in MainActivity as:
Bundle bungle = getIntent().getExtras();
if ( bungle != null) {
Object title = bungle.get("title");
....
}

Related

Firebase message, Android app in background not intercept push notification after click on message

I use firebase messaging to send push notification. I have a small problem with my android app. In the iOS version, I can easily pass parameters after clicking on a notification when the app is in background.
In Android version I can intercept messages when the app is in the foreground, but not when the app is in the background (I use library com.google.firebase:firebase-messaging:17.3.4):
my AndroidManifest.xml
<activity android:name=".MainActivity"
android:screenOrientation="portrait"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="OPEN_NOTIFY" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
....
<service
android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
My notification payload:
notification:{
title: "mytitle",
text: "MYTEXT",
"data":{
"type" : "message",
"id_message" : res
},
"click_action" : "OPEN_NOTIFY"
},to: token
When I click on the notification, it should open the MainActivity and I would like to have the id_message
my MyFirebaseMessagingService.java
#Override
public void onMessageReceived(RemoteMessage remoteMessage){
//never enters if the app is in background
if(remoteMessage.getNotification() != null){
//I READ NOTIFY WHEN APP IS IN FOREGROUND
}
}
I try to get parameters directly from the Inten, but this solution doesn't work
my MainActivity.java:
#Override
protected void onCreate(Bundle savedInstanceState) {
....
if (getIntent().getExtras() != null) {
for (String key : getIntent().getExtras().keySet()) {
Object value = getIntent().getExtras().get(key);
Log.d(TAG, "Key: " + key + " Value: " + value);
}
}
....
}
I can't intercept my notify:
output:
Key: google.sent_time Value: 1540026384768
Key: google.ttl Value: 2419200
Key: from Value: 635549396240
Key: google.message_id Value: 0:1540026384773623%6b8fed3d6b8fed3d
Key: collapse_key Value: ....
Am I following the right path? Thank You
According to official Firebase docs, you can't handle notification{} part of notification (you can only set icon of it in manifest), BUT here's solution: send necessary data via data{} part. You can now handle it with MyFirebaseService and show notification if you want and as you want: data will appear in remoteMessage.toIntent().getExtras().
In your case, send notification like this:
// ignore notification {}
data {
"type" : "message",
"id_message" : res
}
to: key
(do not place data into notification block)
I can write working code of sending and receiving notification, if you want

FCM notification not opening intended activity Android

I am trying to get notification generated by FCM console and I am receiving them but I am unable to override onMessageReceived of FirebaseMessagingService. Don't know what I am doing wrong.
MyFirebaseMessagingService class responsible for handling notifications:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "FROM:" + remoteMessage.getFrom());
//Check if the message contains data
if(remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data: " + remoteMessage.getData());
}
//Check if the message contains notification
if(remoteMessage.getNotification() != null) {
Log.d(TAG, "Mesage body:" + remoteMessage.getNotification().getBody());
sendNotification(remoteMessage.getNotification().getBody(),remoteMessage.getData());
}
}
/**
* Dispay the notification
* #param body
*/
private void sendNotification(String body , Map<String,String> data) {
// int finalSecId = Integer.parseInt((String) data.get("sec_id"));
// int sec = Integer.parseInt((String) data.get("sec"));
Intent intent = new Intent(this, InsuranceActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0/*Request code*/, intent, PendingIntent.FLAG_ONE_SHOT);
//Set sound of notification
Uri notificationSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notifiBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.login_meter)
.setContentTitle(getString(R.string.app_name))
.setContentText((String) data.get("sec_id")+ " "+(String) data.get("sec"))
.setAutoCancel(true)
.setSound(notificationSound)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /*ID of notification*/, notifiBuilder.build());
}
}
And Inside Application tag
<service android:name=".Fcm.MyFirebaseMessagingService"
android:enabled="true"
android:exported="true"
>
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service android:name=".Fcm.MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
There are two types of FCM
notification Messages: Sending a payload with this message type triggers onMessageReceived() only when your app is in foreground.
data Messages: Sending a payload with only this specific message type triggers onMessageReceived() regardless if your app is in foreground/background.
Reference:here
Extending #Sudip Podder comments and #Ratilal Chopda answer
Follow these steps:
Step1:
<activity android:name=".SplashActivity">
<intent-filter>
<action android:name=".SplashActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Step2:
I am using php at server so you need to adjust things the way you like but in notification payload add "click_action" : ".SplashActivity"
$fields = array(
'to' => $token,
'notification' => array(
'title' => 'Motors City',
'body' => $message,
"click_action" => ".AppSplash",
),
'data' => array(
'sec_id' => $secID,
'sec' => $sec,
'extra1'=>$extra1,
'extra2'=>$extra2
)
);
$headers = array(
'Authorization:key=' . $server_key,
'Content-Type:application/json'
);
Step3:
In Oncreate of your SplashActivity
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
Log.d(TAG,bundle.toString);
}}
and you are done
I had this problem of handling the notifications from FCM.
First we have to understand that there are 2 types of notifications.
Notification - It will trigger when your app is not in foreground and generate a notification. If you click on it then it will open the launcher activity.
Data notification - This one is used to parse the data and it is received in background as well as foreground. So you can build a custom notification based on the data provided in the data object by the FCM Push.
Map<String ,String> dataMap = remoteMessage.getData();
Here i created a simple Map with key value pairs. Now i can receive the title of the notification in the data object and make a simple notification with a custom intent.
I personally use a context object to determine if the app is in foreground or background. Based on that i decide if i have to show the notification or just update the data.
Hope this helps.
Right now you are having Notification in notification type, which triggers Notification Default,and Just open the app on the click of the notification.
So you need to change server side code from notification type to data type.
And try to get Message from
`remoteMessage.getData()` not from `remoteMessage.getNotification()`
if you want to manage click of the notification use data type notification.to understand more about this types go through this link
https://firebase.google.com/docs/cloud-messaging/concept-options
Try this
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent, PendingIntent.FLAG_ONE_SHOT);

How to get Firebase Combined Message in Background app

Reading documentation of firebase about cloud message in combined way, I've had problems to get data message in android device.
var payload = {
notification: {
title: "Test",
body: "Test body"
},
data: {
score: "850",
close: "635.67"
}
};
I expect to get data field at 'onMessageReceived' in android device, but I got only a notification message. I tried to tap the message and I still got nothing at 'onMessageReceived'.
I've add a intent filter to trigger the main activity, add 'clickAction'(as referred in firebase reference) and 'click_action'(as I saw in some questions) in notification payload, and I also got the same.
MANIFEST
<meta-data
android:name="com.google.firebase.messaging.default_notification_icon"
android:resource="#mipmap/ic_launcher" />
<meta-data
android:name="com.google.firebase.messaging.default_notification_color"
android:resource="#color/blue" />
<service
android:name=".connection.TestFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service
android:name=".connection.TestFirebaseIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
Java Code:
public class FirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "TestFirebase";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
LogNotification.d(TAG, "NOTIFICATION - From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
LogNotification.d(TAG, "NOTIFICATION - Message data payload: " + remoteMessage.getData().toString());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
LogNotification.d(TAG, "NOTIFICATION - Message Notification Body: " + remoteMessage.getData().toString());
}
}
}
Some tips?
If you have the notification key in your payload then the message becomes a notification message.
Notification messages are displayed automatically when the app is in background.
When the notification is clicked FCM launches your main activity (or another one if you specified click_action)
In the activity you can use getIntent() to get the intent that launched the activity.
If your activity was launched by FCM you will find the data payload in the intent used to launch the activity.

I want to send specific link inside notifications send through firebase push notification,how to do it?

Suppose in my notification,Today is X's birthday it opens FB link of X on clicking the notification and same for Y, How to do it using firebase
Below is the way to do that:
1) server site make request with:
Request URL: https://fcm.googleapis.com/fcm/send
Method: POST
Header:
Content-Type: application/json
Authorization: key=...your_key...
Body:
{
"registration_ids" :[devices_token],
"priority" : "high",
"notification" : {
"body" : "Notification body here",
"title" : "notification title here",
"click_action": "action.open.facebook.with.url"
},
"data" : {
"openURL" : "https://facebook.com/xxx"
}
}
2) Android app:
AndroidManifest.xml:
<activity android:name=".activity.OpenFacebookLink">
<intent-filter>
<action android:name="action.open.facebook.with.url" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
In your subclass of FirebaseMessagingService:
#Override
public void onMessageReceived(RemoteMessage message) {
super.onMessageReceived(message);
String url = message.getData().get("openURL");
if(message.getNotification()!=null) {
// do some thing with url when app in foreground
} else {
// do some thing with url when app in background
}
}
In your OpenFacebookLink activity let do that:
Intent intent = getIntent();
String url = intent.getStringExtra("openURL");
// do open facebook with url
If you want to send the notification manually from FCM panel then:
then make a key like:
link and put the value i.e. your fb link. Then send the notification to that particular user or a topic or a segment from FCM panel.
You can handle it inside your application like:
Extract the data from notification then...
if (data != null) {
directLink = data.optString("directLink");
}
Inside the notification open method:
Intent browserIntent = new Intent(android.content.Intent.ACTION_VIEW,
Uri.parse(link));
browserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(browserIntent);
But if you want to make this process automated then you'll have to write a script that will extract the birthday links from some database and send notifications to users via FCM API and do a post request on that API.

GCM notifications not being recieved when app in foreground

I am trying to setup push notifications to my app containing both data and notification payloads as described in the official reference. I want both payloads so that I will get an automatic notification when my app is in the background, and the app can handle things itself while in the foreground.
The onMessageReceived() method in my GcmListenerService is not called when both payloads are included and the app is in the foreground. I have to leave out the notification payload for it to work.
When the app is in the background, it works fine. I get a notification and can open the app when the notification is clicked and do whatever I want from there.
I have looked at this question, but they were trying to get a notification when the app is in foreground. I realize I won't get a notification in that case, I just want to get the data.
Relevant portion of AndroidManifest.xml:
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="arkenterprises.garage_o_matic.gcm" />
</intent-filter>
</receiver>
<service
android:name=".MyGcmListenerService"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
MyGcmListenerService.java:
public class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService";
#Override
public void onMessageReceived(String from, Bundle data) {
Log.d(TAG, "Data: " + data);
String message = data.getString("message");
String doorStatus = data.getString("DoorStatus");
String time = data.getString("time");
Bundle notification = data.getBundle("notification");
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);
Log.d(TAG, "DoorStatus: " + doorStatus);
Log.d(TAG, "Time: " + time);
Log.d(TAG, "Notification: " + notification);
}
Server code that sends the message:
nowString = datetime.datetime.now().strftime("%c")
gcmSendURL = 'https://gcm-http.googleapis.com/gcm/send'
gcmHeaders = {'Authorization': 'key=' + API_KEY, 'Content-Type': 'application/json'}
gcmDataPayload = {'message': 'Garage door opened', 'DoorStatus': 'Open', 'time': nowString}
gcmNotificationPayload = {'title': 'Garage Door Has Opened', 'body': 'Garage door opened at {}'.format(nowString), 'icon': 'ic_door_open_notification2'}
print('Garage door opened at {}'.format(nowString))
gcmPayload = {'to': regIDs[0].strip(), 'priority': 'high', 'delay_while_idle': False, 'time_to_live': 86400, 'data': gcmDataPayload}
# gcmPayload = {'to': regIDs[0].strip(), 'priority': 'high', 'delay_while_idle': False, 'time_to_live': 86400, 'notification': gcmNotificationPayload}
# gcmPayload = {'to': regIDs[0].strip(), 'priority': 'high', 'delay_while_idle': False, 'time_to_live': 86400, 'content_available': True, 'data': gcmDataPayload, 'notification': gcmNotificationPayload}
print("\nPayload: {}".format(gcmPayload))
r = requests.post(gcmSendURL, headers=gcmHeaders, json=gcmPayload)
print("\nRequest response: " + r.text)
Yes, you can send messages that have both notification and data payloads.
I found this Stack overflow ticket related to your inquiry, It says that Intent filters will always fire your manifested application as per standard android behavior. Make sure that your logic flow is able to handle the fact that your launch may come from places. Try to implement 'GcmMessageHandler' your application must check saved state and sees if user needs to see screen and automatically show notifications.
I had some strange behaviour with samples, but in final I resolved that by removing implementation of GcmListenerService and adding implementation of GcmReceiver.
public class MyGcmReceiver extends GcmReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
}
};
and manifest
<receiver
android:name=".MyGcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</receiver>

Categories

Resources