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.
Related
how to resolve this issue any one give send me any solution according to this issues
fcm notification is received but app not opened how to handle it
public void onMessageReceived(RemoteMessage remoteMessage) {
Intent intent = new Intent(INTENT_FILTER);
sendBroadcast(intent);
if (remoteMessage.getData().size() > 0) {
utils.print(TAG, "From: " + remoteMessage.getFrom());
utils.print(TAG, "Notification Message Body: " + remoteMessage.getData());
//Calling method to generate notification
if (SharedHelper.getKey(this,"loggedIn").equalsIgnoreCase(getString(R.string.True))) {
sendNotification(remoteMessage.getData().get("message"));
}
}
you should declare the firebase service class in Manifest like this:
<service android:name="your_service>
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
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");
....
}
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
I am using FCM for notification and it is working good in all scenarios in Foreground and background. My problem is when I am logout from my application and another user send me message, I am not getting any notification as I am logout which is fine, but when I again login in my application I want to receive that old unread notification so how to do this any help would be appreciated following is the code I used
public class FirebaseIDService extends FirebaseInstanceIdService {
private static final String TAG = "FirebaseIDService";
Context ctx = this;
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
try {
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FCM Service";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
Log.e("remote", remoteMessage.getData().get("type") + "");
Log.e("remoteMessage", remoteMessage.getData() + "");
Log.e("remoteMessagebody", remoteMessage.getData().get("body") + "");
// handling other data also according to my app which i am not mentioning
}
}
I have used this code for fetching old notification but didnot worked
FirebaseDatabase.getInstance().setPersistenceEnabled(true);
and in manifest
<service
android:name=".MyFirebaseMessagingService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".FirebaseIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
and in gradle
compile 'com.google.firebase:firebase-messaging:9.2.1'
An FCM message has its own lifetime -- 4 weeks default, could be modified by setting time_to_live in your payload. After that time, the message would be discarded.
What you could do is implement that each notif is saved in a your Server DB, if it is not read yet and you detect that the user re-logs in, re-send them as push notifications, or simply retrieve them in your app and display them as notifications.
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>