I am using FCM in my project and when trying to test the incoming notifications with the firebase "compose notification" feature I am putting a title, a body and an image URL to the message and it shows what it should look like - a rich notification with image. But the notification that is being sent to me is a normal one without any image.
here is the firebase UI and what is suposed to happen -
My issue is that I am getting only the text, without the image.
here is my MyFirebaseMessagingService class -
public class MyFirebaseMessagingService extends FirebaseMessagingService {
public static final String RECEIVED_FCM_ACTION = "com.onemdtalent.app.RECEIVED_FCM_ACTION";
public static final String BD_KEY_BODY = "BD_KEY_BODY";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// [START_EXCLUDE]
// There are two types of messages data messages and notification messages. Data messages are handled
// here in onMessageReceived whether the app is in the foreground or background. Data messages are the type
// traditionally used with GCM. Notification messages are only received here in onMessageReceived when the app
// is in the foreground. When the app is in the background an automatically generated notification is displayed.
// When the user taps on the notification they are returned to the app. Messages containing both notification
// and data payloads are treated as notification messages. The Firebase console always sends notification
// messages. For more see: https://firebase.google.com/docs/cloud-messaging/concept-options
// [END_EXCLUDE]
String image = remoteMessage.getData().get("image");
Timber.d("onMessageReceived: %s", remoteMessage.getFrom());
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
String body = remoteMessage.getNotification().getBody();
Timber.d("Message Notification Body: %s", body);
// broadcast
Intent localIntent = new Intent(RECEIVED_FCM_ACTION);
localIntent.putExtra(BD_KEY_BODY, image);
LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
}
}
}
As I sayed, I am getting only the text without the image. what am I missing?
Solved - I used an old version of firebase messaging dependency and I updated it, including my entire project to androidX and now I can see the images :)
Related
can i intercept notifications when my app is closed?
I need for set badge with this library ShortcutBadger
Thanks.
There are 3 types of notifications:
notification: Can be send from the web console or any backend, it has predefines values. If the app is open the behaviour is customizable on onMessageRecieve if the app is closed triggers a default notification.
data: a key value pair, only Strings. Can be send from any backend. The behaviour is always defined in onMessageReceived method.
notification and data: Combination of previous it will have the behaviour of a notification, the data will be available as extras once the notification is clicked in the default launcher activity. Can be send from the web console or any backend.
A push is a json called Payload which contains those objects:
payload: {
data: {...}
}
Yes, you can send yourself a data type notification it will always do what you write in the onMessageReceived method inside the MessagingService.
This doc should help you
https://firebase.google.com/docs/cloud-messaging/concept-options?hl=es-419
If you dont have a server use Functions.
Since the default notification wont be shown, you will probably want to show your own.
If you want to also show a notification then the NotificationCompat class must be called from inside onMessageReceived. The visual notification is not related to the push message, in fact, a visual notification can be triggered by pressing a button.
For creating a visual notification, the best approach is to let Android Studio do it for you. Second click on the packages where your activities .java are, new, then selecet ui-component and there is the notification. It will create a basic template of a notification. Then use those methods inside onMessaReceived passing the info that has to be show to the user.
The docs about the class
https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html
And you will probably find this error
NotificationCompat.Builder deprecated in Android O
In case you never solved this, the problem is not how you are implementing it within your app, but how the JSON data payload is being sent. See this question and the respective answers for why you are not receiving the messages while they are in the background.
Very short summary is, if you are receiving the notification payload, it will never trigger in the background. If you receive the data payload without notification, you can parse and perform actions while the app is in the background.
do you mean it?
public class AppFcmMessagingsService extends FirebaseMessagingService {
private static final String TAG = "FirebaseMessageService";
#Override
public void onCreate() {
super.onCreate();
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
try {
if(remoteMessage.getData().size() > 0) {
final JSONObject jsonObject = new JSONObject(remoteMessage.getData().toString());
Log.d(TAG,"remoteMessage = " + jsonObject.toString());
int badgeCount = 1;
ShortcutBadger.applyCount(getApplicationContext(), badgeCount);
}
} catch (Exception e) {
Log.e(TAG, "onMessageReceived: ", e);
}
if(remoteMessage.getNotification() != null) {
int badgeCount = 1;
ShortcutBadger.applyCount(getApplicationContext(), badgeCount);
Log.d(TAG, "notification body : " + remoteMessage.getNotification().getBody());
}
}
}
I set up the Firebase messaging with my app, but unfortunately the notifications are not coming.
I set up Firebase properly, it is connected to my app, I also sent some test messages, in the Firebase it says completed, however I did not receive them on my phone.
My app is not in the store yet, I am developing and testing it via Android studio.
Here is my MyFirebaseInstanceIDService class
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private static final String TAG = "MyFirebaseIIDService";
/**
* Called if InstanceID token is updated. This may occur if the security of
* the previous token had been compromised. Note that this is called when the InstanceID token
* is initially generated so this is where you would retrieve the token.
*/
// [START refresh_token]
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
// TODO: Implement this method to send any registration to your app's servers.
sendRegistrationToServer(refreshedToken);
}
// [END refresh_token]
/**
* Persist token to third-party servers.
*
* Modify this method to associate the user's FCM InstanceID token with any server-side account
* maintained by your application.
*
* #param token The new token.
*/
private void sendRegistrationToServer(String token) {
// Add custom implementation, as needed.
}
}
and here comes the MyFirebaseMessagingService class:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
/**
* Called when message is received.
*
* #param remoteMessage Object representing the message received from Firebase Cloud Messaging.
*/
// [START receive_message]
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// [START_EXCLUDE]
// There are two types of messages data messages and notification messages. Data messages are handled
// here in onMessageReceived whether the app is in the foreground or background. Data messages are the type
// traditionally used with GCM. Notification messages are only received here in onMessageReceived when the app
// is in the foreground. When the app is in the background an automatically generated notification is displayed.
// When the user taps on the notification they are returned to the app. Messages containing both notification
// and data payloads are treated as notification messages. The Firebase console always sends notification
// messages. For more see: https://firebase.google.com/docs/cloud-messaging/concept-options
// [END_EXCLUDE]
//"Title","Message","NotyType", "hotelStatus"
String title = "";
if (remoteMessage.getNotification().getTitle() != null){
title = remoteMessage.getNotification().getTitle();
}
String message = "";
if (remoteMessage.getNotification().getBody() != null){
message = remoteMessage.getNotification().getBody();
}
Log.e("notification","recieved");
sendNotification(title, message);
// Also if you intend on generating your own notifications as a result of a received FCM
// message, here is where that should be initiated. See sendNotification method below.
}
// [END receive_message]
private void sendNotification(String title, String body) {
Intent i = new Intent(this, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pi = PendingIntent.getActivity(this,
0 /* Request code */,
i,
PendingIntent.FLAG_ONE_SHOT);
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this,
getString(R.string.default_notification_channel_id))
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(body)
.setAutoCancel(true)
.setSound(sound)
.setContentIntent(pi);
NotificationManager manager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
assert manager != null;
manager.notify(0, builder.build());
} }
I don't see any logs when debugging, also don't receive any notifications on the phone.
Am I doing something wrong here? Can you please advice? Thanks.
onMessageReceived does not get called with a push sent with just notification tag and your app isn't in foreground. If it is indeed in foreground, your onMessageReceived will get called.
If you want your onMessageReceived to get triggered, you will need to send the push with an additional data tag or just the data tag.
However note, if you send both notification and data tags, your onMessageReceived will only get triggered if your app is in foreground, If it's in background, everything inside the data tag will be passed inside an click intent as extras
Only a Data tag will always call onMessageReceived regardless of whether you app is in foreground or not.
Eg: for just a data tag :)
https://fcm.googleapis.com/fcm/send
Content-Type:application/json
Authorization:key=AIzaSyZ-1u...0GBYzPu7Udno5aA
{ "data": {
"score": "5x1",
"time": "15:10"
},
"to" : "bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1..."
}
OH now I tried something! I updated my MyFirebaseMessagingService class as you see in my question now, and now it WORKS! From Firebase console I sent only message, no data, and all the notifications I received in my device! Even if my app is running, even if I closed it! Every notification I received. When the app was running, the notification has my custom icon, and when the app is closed, the default "bell" icon is there, but in both cases I received the notifications! Not sure how it is possible, but it works.
I am following this tutorial to implement Firebase Push Notification functionality within my app.
But I found one thing, if app is in foreground then only I am getting (showing) message in a Toast and TextView.
Other hand, If app is in background on tap neither I am not getting message to show in a TextView and Toast.
Whereas I would like to show message in Toast and TextView in both the situations (Either App is in Foreground or Background).
NOTE: I am pushing message from Firebase console itself.
Is it possible ?
MyFirebaseMessagingService.java
private void handleNotification(String message) {
if (!NotificationUtils.isAppIsInBackground(getApplicationContext())) {
// app is in foreground, broadcast the push message
Intent pushNotification = new Intent(Config.PUSH_NOTIFICATION);
pushNotification.putExtra("message", message);
LocalBroadcastManager.getInstance(this).sendBroadcast(pushNotification);
// play notification sound
NotificationUtils notificationUtils = new NotificationUtils(getApplicationContext());
notificationUtils.playNotificationSound();
}else{
// If the app is in background, firebase itself handles the notification
}
}
MainActivity.java
mRegistrationBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// checking for type intent filter
if (intent.getAction().equals(Config.REGISTRATION_COMPLETE)) {
// gcm successfully registered
// now subscribe to `global` topic to receive app wide notifications
FirebaseMessaging.getInstance().subscribeToTopic(Config.TOPIC_GLOBAL);
displayFirebaseRegId();
} else if (intent.getAction().equals(Config.PUSH_NOTIFICATION)) {
// new push notification is received
String message = intent.getStringExtra("message");
Toast.makeText(getApplicationContext(), "Push notification: " + message, Toast.LENGTH_LONG).show();
txtMessage.setText(message);
}
}
};
FCM has two types of messages, Notification and Data. Use notification messages when you want FCM to handle displaying a notification on your client app's behalf. Use data messages when you want to process the messages on your client app.
Below is the sample,
{
"to": “token ID”,
"notification": {
//params
},
"data": {
//params
}
}
Behaviour when the payload with types of messages,
Notification Messages
Foreground - onMessageReceived fired
Background - Notification appears on the System tray and handled by FCM
App not running - Notification appears on the System tray and handled by FCM
Data Messages
Foreground - onMessageReceived
Background - onMessageReceived
App not running - onMessageReceived
Both Notification and Data
Foreground - onMessageReceived
Background - Notification in the tray and the data payload will be handled via extras of the intent on tap
App not running - Notification in the tray and the data payload will be handled via extras of the intent on tap.
Hope it helps!
I am using Firebas mesaging service class. and Its working properly when app is running in foreground but when i clear this application from recent i am not able to access the push notification data for setting it on textview.
I want to store data in database when app is running in background.
I had Used Database to store the value directly but its not working.
public void onMessageReceived(RemoteMessage message) {
database=new SQLiteHelper(getApplicationContext());
database.open();
String image = message.getNotification().getIcon();
String title = message.getNotification().getTitle();
String text = message.getNotification().getBody();
String sound = message.getNotification().getSound();
int id = 0;
database.addQuotes(text,"Xyz");
}
In MainActivity.java in Oncreate method
Bundle extras = getIntent().getExtras();
if (extras != null) {
final String message = extras.getString("message");
quote_text.setText(message);
Toast.makeText(this, "A", Toast.LENGTH_SHORT).show();
}
But message shows null data.
based on this:
I want to store data in database when app is running in background
The service calls which extends FirebaseMessagingService has a method called onMessageReceived which is called when a push notification is received on the front-end (app) add your message to DB there!
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
.....
// parse and add your message to Db here!
Normally when your app is in the background, Android directs notification messages to the system tray. A user tap on the notification opens the app launcher by default.
This includes messages that contain both notification and data payload (and all messages sent from the Notifications console). In these cases, the notification is delivered to the device's system tray, and the data payload is delivered in the extras of the intent of your launcher Activity.
But you can refer this answer on stackoverflow if you want to get notification data-messages in your app while in background.
You may also refer this
As instructed in Firebase dev docs, I've implemented a Service that extends FirebaseMessagingService and overrides the onMessageReceived callback. I have put a Log message in the first line inside the onMessageReceived method.
App running in background
I don't see the log in logcat but I see a Notification posted in the system try.
App in Foreground
I neither see the log nor the notification in system tray
Any idea what's going on?
Manifest
<service
android:name=".fcm.MovieMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
Service Class
public class MovieMessagingService extends FirebaseMessagingService {
private static final String LOG_TAG = MovieMessagingService.class.getSimpleName();
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(LOG_TAG, "From: " + remoteMessage.getFrom());
}
/**
* Create and show a simple notification containing the received FCM message.
*
* #param messageBody FCM message body received.
*/
private void sendNotification(String messageBody) {
Log.d(LOG_TAG, "Presenting Notification with message body: " + messageBody);
//more code
}
}
Actually, app's behavior, while receiving messages including both notification and data payloads, depends on whether the app is in the background or the foreground like:
When in the background, apps receive the notification payload in the notification tray, and only handle the data payload when the user taps on the notification.
When in the foreground, your app receives a message object with both payloads attached.
So, The summary is when app is in background, you can see the notification in system tray and can't see any log until tapping on the notification but you will see only the opening activity log not the service log as it's already executed.
And when the app in foreground you can see the log in logcat but you can't see any notification in the system tray as your app already open state you will receive only data payloads.
Here is a code example of how to receive messages and how to handle the different types. Here is the source of the code.
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
/**
* Called when message is received.
*
* #param remoteMessage Object representing the message received from Firebase Cloud Messaging.
*/
// [START receive_message]
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// [START_EXCLUDE]
// There are two types of messages data messages and notification messages. Data messages are handled
// here in onMessageReceived whether the app is in the foreground or background. Data messages are the type
// traditionally used with GCM. Notification messages are only received here in onMessageReceived when the app
// is in the foreground. When the app is in the background an automatically generated notification is displayed.
// When the user taps on the notification they are returned to the app. Messages containing both notification
// and data payloads are treated as notification messages. The Firebase console always sends notification
// messages. For more see: https://firebase.google.com/docs/cloud-messaging/concept-options
// [END_EXCLUDE]
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
}