I am dealing with FCM messages and I have the following function:
public void onMessageReceived(final RemoteMessage remoteMessage)
{
final Map<String, String> data = remoteMessage.getData();
//...
}
For testing purposes, I have a Json file containing data- and I want to send that Json file from my test method to onMessagereceived() . Hence I need to initialize a RemoteMessage object with the Json file and pass this RemoteMessage object to the function. How do I initialize this?
My JSON file:
{
"data": {
"id" : "4422",
"type" : "1",
"imageUrl" : "https://image.freepik.com/free-vector/android-boot-logo_634639.jpg",
"smallTitle" : "DoJMA v2",
"smallSubTitle" : "Update now from Google Play Store",
"ticker" : "New update for DoJMA",
"contentInfo" : "",
"link" : "https://photo2.tinhte.vn/data/avatars/l/1885/1885712.jpg?1402763583",
"className" : "HomeActivity",
"page" : "2",
"bigTitle" : "DoJMA Android app version 2 released!",
"bigSubTitle" : "Hi folks! New DoJMA update is here! Major redesigning and improvements! This app was made by the Mobile App Club.They work really hard man...and get good products",
"bigSummaryText" : "Update now"
},
"registration_ids": ["dQYmpLUACXQ:APA91bGl-NoIMJ2_DcctF5-OA8ghyWuyrMfsz3uhlj1BySl6axkAsmv5y_7YGfpQQJ2E0lP_fTcxpHpZdkJzY1tbcWA36e78ooxC_b0a1PAank9gFIAUHVZkHKmZT70MPZosCgvRlVfq","dfLXnRI36qY:APA91bFyjLblijVIjGLCGWVeB1B0z5j_3TYqRytJ-8hvuUESpDlX59gWF3hU-I-kA4VrRCPpEVFWl18ZarnPjqxxtZgFkVxoLr77HRex27VN7Mh3xupWykmKq_nnVIlVzrODKwKI7ktM"]
}
you can test using Postman For Single User.
Send a notification with a JSON payload
URL: https://fcm.googleapis.com/fcm/send
Headers:
Authorization: key=<your-api-key>
Content-Type: application/json
Body (click on the 'raw' tab):
{
"to": "dQYmpLUACXQ:APA91bGl-NoIMJ2_DcctF5-OA8ghyWuyrMfsz3uhlj1BySl6axkAsmv5y_7YGfpQQJ2E0lP_fTcxpHpZdkJzY1tbcWA36e78ooxC_b0a1PAank9gFIAUHVZkHKmZT70MPZosCgvRlVfq",
"data": {
"id": "4422",
"type": "1",
"imageUrl": "https://image.freepik.com/free-vector/android-boot-logo_634639.jpg",
"smallTitle": "DoJMA v2",
"smallSubTitle": "Update now from Google Play Store",
"ticker": "New update for DoJMA",
"contentInfo": "",
"link": "https://photo2.tinhte.vn/data/avatars/l/1885/1885712.jpg?1402763583",
"className": "HomeActivity",
"page": "2",
"bigTitle": "DoJMA Android app version 2 released!",
"bigSubTitle": "Hi folks! New DoJMA update is here! Major redesigning and improvements! This app was made by the Mobile App Club.They work really hard man...and get good products",
"bigSummaryText": "Update now"
}
}
Source : https://firebase.google.com/docs/cloud-messaging/concept-options
TL;DR: Initializing a RemoteMessage object is not possible.
Attempting to access initialize a RemoteMessage from your own class would return an error:
'RemoteMessage(android.os.Bundle)' is not public in 'com.google.firebase.messaging.RemoteMessage'. Cannot be accessed from outside package.
I presume you're attempting to do this for testing purposes (stubbing?). In general (not gonna say best practice, since I'm not that entirely sure that it is best practice), it is advisable to have a separate method that accepts a specific value that you need. Referring to the official example (onMessageReceived) (removed some stuff):
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
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());
if (/* Check if data needs to be processed by long running job */ true) {
// For long-running tasks (10 seconds or more) use Firebase Job Dispatcher.
scheduleJob();
} else {
// Handle message within 10 seconds
handleNow();
}
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
// 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.
}
/**
* Schedule a job using FirebaseJobDispatcher.
*/
private void scheduleJob() {
// [START dispatch_job]
FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(this));
Job myJob = dispatcher.newJobBuilder()
.setService(MyJobService.class)
.setTag("my-job-tag")
.build();
dispatcher.schedule(myJob);
// [END dispatch_job]
}
/**
* Handle time allotted to BroadcastReceivers.
*/
private void handleNow() {
Log.d(TAG, "Short lived task is done.");
}
/**
* Create and show a simple notification containing the received FCM message.
*
* #param messageBody FCM message body received.
*/
private void sendNotification(String messageBody) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_ic_notification)
.setContentTitle("FCM Message")
.setContentText(messageBody)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
Focusing on the comment that mentions:
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.
This points out the sendNotification() method that accepts a String parameter. Depending on your case, instead of attempting to pass an initialized RemoteMessage (which sadly isn't possible, or at the very least is not advisable), you could simply pass an object that your method needs.
With that, you pretty much tested the method that handles the message without depending on an object that isn't a class you made in the first place.
PS: Some of my explanations can be confusing, but I hope this made sense.
Related
In my android app I am using Firebase messaging via topics. I am ocassionally sending notifications to my application via Postman to the users which are in that topic:
"notification" : {
"title" : "some title in local lang",
"body" : "some text in local lang",
"sound" : "default"
},
"data": {
"title": "some title in local lang",
"message": "some msg in local lang",
"sound" : "default"
}
I just want to show at least the notification title in english language if the user has switched the language in my app to english.
This is the MyFirebaseMessagingService class, where I tried to work with the notification text, but it doesn't work, it always shows the notification in the sent language, not the app language:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
/**
* 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) {
String title = "";
if (Objects.requireNonNull(remoteMessage.getNotification()).getTitle() != null){
title = remoteMessage.getNotification().getTitle();
}
String message = "";
if (remoteMessage.getNotification().getBody() != null){
message = remoteMessage.getNotification().getBody();
}
String lng = readLang();
if (lng.equals("en")) {title="New object added";}
if (readState()) {
sendNotification(title, message);
} }
private void sendNotification(String title, String body) {
Intent i = new Intent(this, Novinky.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);
String lng = readLang();
if (lng.equals("en")) {title="New object added";}
NotificationCompat.Builder builder = new NotificationCompat.Builder(this,
getString(R.string.default_notification_channel_id))
.setSmallIcon(R.mipmap.ic_notify)
.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());
}
private boolean readState() {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
return sharedPreferences.getBoolean("State", true);
}
private String readLang() {
SharedPreferences sharedPreferences = androidx.preference.PreferenceManager.getDefaultSharedPreferences(this);
return sharedPreferences.getString("hrady_langx", "sk");
}
}
So in both cases (sendNotification and onMessageReceived) I check if (lng.equals("en")) and then define an english title, but this works not...
I found this solution, to use title_loc_key instead of title in Postman data.
Resources/values/strings.xml (default file)
<string name="notification_title_string">Local title</string>
Resources/values-en/strings.xml (English strings file)
<string name="notification_title_string">English title</string>
On the payload instead of using title and message / body keys, we will use title_loc_key to represent the key for our localized title and body_loc_key to represent the key for our localized message.
When sending the payload would look like this:
{
"data": {
"title_loc_key": "notification_title_string",
"body_loc_key": "notification_message_string"
},
"priority": "high",
"condition": "'test' in topics"
}
I will test it when I send the next notification.
Ok, finally I found out - I am now sending only DATA payload, created a notification channel and then I can handle title and message inside onMessageReceived. Now this is working as I wanted.
This question already has an answer here:
How set Firebase notification ChannelID in Android O?
(1 answer)
Closed 3 years ago.
I followed official sample and extends FirebaseMessagingService
<service android:name=".service.MyFirebaseMessagingService"
android:stopWithTask="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
and my push json
{
"message":{
"token":"my fcm token",
"android":{
"priority": "high",
"data":{
"key1":"123","key2":"456"
}
}
}
}
I reveived fcm from
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {}
until I killed my app from recent application.
My android os is Android 8.1 (API level 27)
I have test on android 7.1(API level 25), it can receive message, even app got killed.
See this part :
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
System.out.println("Remote Data" + remoteMessage);
//Check if msg contains Data'
if (remoteMessage.getData().size() > 0) {
System.out.println("Message Data : " + remoteMessage.getData());
sendNotification(remoteMessage.getData().get("body"));
}
//Check if message contains notification
if (remoteMessage.getNotification() != null) {
System.out.println("Message Body " + remoteMessage.getNotification().getBody());
sendNotification(remoteMessage.getNotification().getBody());
}
}
Reference link :
Check Here
Deat #youteng notification in oreo must needed Channel Id inside notification builder object. So check in your code if you have added channel id or not. you can have look in below code. Also have look here
// Sets an ID for the notification, so it can be updated.
int notifyID = 1;
String CHANNEL_ID = "my_channel";// channel id
CharSequence name = getString(R.string.channel_name);// The user-visible name of the channel.
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID, name, importance);
// Create a notification and set the notification channel.
Notification notification = new Notification.Builder(MainActivity.this)
.setContentTitle("New Message")
.setContentText("You've received new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
.setChannelId(CHANNEL_ID)
.build();
There are so many details while implementing FCM. Use tools to check the sender side and receiver side. And there comes the background/foreground parts.
If your message format aren't correct, it will not trigger onReceive() when app is in background.
By correct I mean it contains only data{...}, without notification{...}
Before dig into your server side's code, have you test your client side by sending a message from Firebase Console's web tool or the FCM API?
POST https://fcm.googleapis.com/fcm/send
I don't know what language you're using on server side, but the original message should look like this (from official)
POST https://fcm.googleapis.com/v1/projects/myproject-b5ae1/messages:send HTTP/1.1
Content-Type: application/json
Authorization: Bearer ya29.ElqKBGN2Ri_Uz...HnS_uNreA
{
"message":{
"topic" : "foo-bar",
"notification" : {
"body" : "This is a Firebase Cloud Messaging Topic Message!",
"title" : "FCM Message"
}
}
}
I'm trying to send the click-action data with the notification to handle the onClick event for it but unfortunately the app receives no data through the onMessageReceived(). I have tried plenty of things but all in vain.
Here is my code:
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
String notification_title =
remoteMessage.getNotification().getTitle();
String notification_message =
remoteMessage.getNotification().getBody();
String click_action =
remoteMessage.getNotification().getClickAction();
String from_user_id = remoteMessage.getData().get("from_user");
Log.v("user id", from_user_id);
if(from_user_id!= null){
Toast.makeText(this, from_user_id, Toast.LENGTH_SHORT).show();
}
NotificationCompat.Builder mBuilder = new
NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(notification_title)
.setContentText(notification_message)
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
Intent resultIntent = new Intent(click_action);
resultIntent.putExtra("user_id", from_user_id);
Log.v("user id", from_user_id);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntentWithParentStack(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
int mNotificationID = (int)System.currentTimeMillis();
NotificationManager mNotifyManger =
(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
mNotifyManger.notify(mNotificationID, mBuilder.build());
}
and here is my mainfest:
<service android:name=".FirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
and this is my gradle:
implementation 'com.google.firebase:firebase-core:16.0.4'
implementation 'com.google.firebase:firebase-database:16.0.3'
implementation 'com.google.firebase:firebase-storage:16.0.3'
implementation 'com.google.firebase:firebase-auth:16.0.5'
implementation 'com.firebaseui:firebase-ui-database:4.2.1'
implementation 'com.google.firebase:firebase-messaging:17.3.4'
Edited:
Here is the data I'm expecting:
const deviceToken =
admin.database().ref(`/Users/${user_id}/device_token`).once('value');
return deviceToken.then(result => {
if (!result || !result.exists){throw new Error("Profile doesn't exist")}
const token_id = result.val();
const payload = {
notification: {
title: "New Friend Request",
body: `${userName} has sent you a Friend Request`,
icon: "default",
click_action: "com.example.alaa.lapitchatapp.Target_Notification"
},
data:{
from_user: from_user_id
}
};
If your RemoteMessage contains notification key onMessageReceived is only called if your app in background.
Move notification part into data. If you have notification setup from the request, FCM uses system notification tray to display the notification you wouldn't have any control over it, On the other hand if you need to process the push response, You should avoid using the notification part in the request
const payload = {
data:{
from_user: from_user_id,
title: "New Friend Request",
body: `${userName} has sent you a Friend Request`,
icon: "default",
click_action: "com.example.alaa.lapitchatapp.Target_Notification"
}
};
Firstly, are you passing your device's firebase ID in the payload? If yes, Please update your payload body mentioned. I don't see it there.
Your payload must have the firebase ID something like this :
"registration_ids":[
"your device's firebase ID"
]
or
"to":"your device's firebase ID"
or
"token":"your device's firebase ID"
Secondly, I don't see the point of this code :
if (true) {
Log.d(TAG, "Message data payload: there is not a problem");
} else {
// Handle message within 10 seconds
Log.d(TAG, "Message data payload: there is a problem");
}
What is the point of an else for an if statement which is always true?
Thirdly, the click action value you have given in the payload - com.example.alaa.lapitchatapp.Target_Notification
Is this a class you are trying to open on click of the notification?
I've found the answer to my question after too much digging in the firebase documentation.
You'll find it there:
Firebase Message Service not called but one time only
Thank you All.
I am making a simple messaging app using firebase cloud messaging service but and I am using cloud functions to handle the notifications, however whenever I test it it always says successful in the logs but the devices receive nothing
Here is the cloud function used :
exports.sendNotifications = functions.database.ref('/meesages/{messageId}').onCreate(event => {
var eventSnapshot = event.data;
var str1 = "Sender : ";
var str = str1.concat(eventSnapshot.child("messageOwner").val());
console.log(str);
var topic = "Messaging";
var payload = {
notification: {
Message: eventSnapshot.child("messageText").val(),
Sender: eventSnapshot.child("messageOwner").val()
}
};
// Send a message to devices subscribed to the provided topic.
return admin.messaging().sendToTopic(topic,payload)
.then(function (response) {
// See the MessagingTopicResponse reference documentation for the
// contents of response.
console.log("Successfully sent message:", response);
})
.catch(function (error) {
console.log("Error sending message:", error);
});
});
Here is the class responsible for handling the notifications part on the android device :
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
showNotification(remoteMessage.getData().get("Sender"), remoteMessage.getData().get("Message"));
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
}
}
#Override
public void onDeletedMessages() {
super.onDeletedMessages();
}
private void showNotification(String Message, String Sender) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
.setContentTitle("New message : " + Message)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentText("By : " + Sender)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
and yes I made sure to add the topic subscription in the mainactivity class
FirebaseMessaging.getInstance().subscribeToTopic("Messaging");
so what is exactly wrong here ??
The code in onMessageReceived() expects the message to have a data payload. This is explained in the documentation, which includes three tabs, showing notification, data, and combined payloads. Change notification to data:
var payload = {
data: {
Message: eventSnapshot.child("messageText").val(),
Sender: eventSnapshot.child("messageOwner").val()
}
};
I'm trying to implement FCM notification in my app. I have read FCM data message type will receive notification even when app is in background so am trying to implementing that in onMessageRecieved method am getting unexpected response like this:
{title =2, message={"Status":"UNASSIGNED","CompanyName":"gd","LastModifiedDateTime":"2017-04-25 18:59:41","IsPartRequired":false,"ProblemCategory":"CONFIGURATION","IsGeneralClaim":false,"RegistrationID":1057,"IncidentCode":"INS\/2017\/04\/25-0010","StatusID":0,"CreatedDateTime":"2017-04-25 18:59:41","IsInstallationCall":false}}
Don't know how to parse this get separate value from title and message let me post my firebase message code:
public class FireBaseMessage extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
Map<String,String> data = remoteMessage.getData();
Log.d(TAG, "From: " + data.toString());
//
}
}
In this log message am getting response like that how to get value from that is try like:
int title=data.get("title");
getting null pointer as this is not in valid format. In my server side i have am trying to post json format like this:
{
"to":"es_OToDkj00:APA91bFqxbVMAaXy5fPtDbNVAkIwyVrPCmfGci2otHZPvdRoXPv-oDdjgtLR92Nqe8w6f57nCVceLbc3_zBWsInG9g1Pfdp3LvsMKyuaiYps0L1y3tn0N0XbzGseEI6jyiqs1r-sT9lb",
"data":{
"message":{
"RegistrationID":1057,
"IncidentCode":"INS/2017/04/25-0010",
"CompanyName":"ABM INFOTECH",
"StatusID":5,
"Status":"ASSIGNED",
"CreatedDateTime":"2017-04-25T12:03:45",
"LastModifiedDateTime":"2017-04-25T18:59:41",
"ProblemCategory":"CONFIGURATION",
"IsPartRequired":false,
"IsInstallationCall":false,
"IsGeneralClaim":false
},
"title ":"1"
}
Don't know where I'm making a mistake. Can anyone help me? Thanks in advance!
To get the Title: from message payload
use:
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
// Check if message contains a data payload.
//In case when notification was send in "notification" parameter we need to check wheather data is null or not.
if (remoteMessage.getData()!=null && remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData());
String title = remoteMessage.getData().get("title").toString();
}
}
EDIT
check if your remoteMessage contain the specific key:
if (remoteMessage.getData()!=null){
for (Map.Entry<String, String> entry : remoteMessage.getData().entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
Log.d(TAG, "key, " + key + " value " + value);
}}
There are two types of FCM messages:
1) Notification Messages
2) Data Messages
Notification Message Structure:
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"notification":{
"title":"Portugal vs. Denmark",
"body":"great match!"
}
}
}
In order to get data from the notification payload/messages:
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message From " + remoteMessage.getFrom()); //sender ID
Log.d(TAG, "Notification Title " + remoteMessage.getNotification().getTitle()); //notification title
Log.d(TAG, "Notification Body " + remoteMessage.getNotification().getBody()); //notification body
}
}
Data Message Structure:
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...",
"data":{
"Nick" : "Mario",
"body" : "great match!",
"Room" : "PortugalVSDenmark"
}
}
}
In order to get data from the data payload/messages:
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Data: " + remoteMessage.getData()); //Whole data
Log.d(TAG, "Key Data : " + remoteMessage.getData().get("key").toString()); //Get specific key data
}
}
You have an extra space character in your "title" parameter:
"title ":"1"
It's hard to see since it's just a space. It should be:
"title":"1"
The reason you're note getting any value is because technically, the key being sent is "title " (with a space), while in your client code, you're only using "title" (without a space).
You should be able to receive it correctly after you remove the extra space.
After many search I have found this answer, it working perfect
To make firebase library to call your onMessageReceived() in the following cases
App in foreground
App in background
App has been killed
you must not put JSON key 'notification' in your request to firebase API but instead use 'data', see below.
The following message will not call your onMessageReceived() when your app is in the background or killed, and you can't customize your notification.
{
"to": "/topics/journal",
"notification": {
"title" : "title",
"text": "data!",
"icon": "ic_notification"
}
}
but instead using this will work
{
"to": "/topics/dev_journal",
"data": {
"text":"text",
"title":"",
"line1":"Journal",
"line2":"刊物"
}
}
Basically, the message is sent in the argument RemoteMessage along with your data object as Map, then you can manage the notification in onMessageReceived as in the snippet here
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> data = remoteMessage.getData();
//you can get your text message here.
String text= data.get("text");
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
// optional, this is to make beautiful icon
.setLargeIcon(BitmapFactory.decodeResource(
getResources(), R.mipmap.ic_launcher))
.setSmallIcon(smallIcon) //mandatory
.......
/*You can read more on notification here:
https://developer.android.com/training/notify-user/build-notification.html
https://www.youtube.com/watch?v=-iog_fmm6mE
*/
}
reference: How to handle notification when app in background in Firebase