I am using cloud messaging from firebase with my android app, I am trying to receive a realtime update without refreshing the activity and getting data from the database, so when a user sends another user a message, this last user will receive a notification, anyone knows how to guide me in the right direction?
In the Firebase service FirebaseMessagingService you implement the method onMessageReceived in such a way that lets you update the chat based on the infos in the notification.
For example, to get the data needed from the notification message:
String sender = null;
int chatId;
String msg = null;
public void onMessageReceived(RemoteMessage remoteMessage) {
//YOU NEED TO USE DATA MESSAGES TO CARRY ALL THE INFORMATION ABOUT THE MESSAGE
Map<String,String> data = remoteMessage.getData();
title = data.get("sender");
msg = data.get("body");
chatId = data.get("chatId");
//this function implements the updating of the chat with the new message received
updateChat(chatId,sender,msg);
}
This code example is based on a push notification message data payload that looks like:
{
"Message": {
"Token": client_device_token,
"Data": {
"sender": "John",
"chatId": chatId_between_me_and_Jhon,
"body": "Hi you, this is John"
}
}
}
The implementation of the method updateChat(chatId,sender,msg) is up to you and depends on the logic of your app and your database.
Related
The custom tagged data defined in message payload like this.
{
"message": {
"notification": {
"title": "message title",
"body": "message body"
},
"android": {
...
},
"token": [
"pushtoken1"
]
},
"custom_data": ...
}
And I want to get this custom_data from RemoteMessage object.
public class HmsService extends HmsMessageService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
// remoteMessage.getCustomData
}
}
How to code this function?
Update
Refer the document
,you can try the following sample code:
Huawei Push Kit supports two types of messages: notification messages and data messages.
According to the data you send, you are using Notification message. The customized array of Notification message cannot be directly sent to the app. Data needs to be transferred through ClickAction method.
The user-defined data can be directly transferred to the data field in a Data Messages,and you can use onMessageReceived method to receive it.
For more details, you can refer to the following Docs:
Sending Downlink Messages
Passing Parameters Through ClickAction
Receiving Messages
Try with the following code.
if (remoteMessage.getData().containsKey("custom_data")) {
remoteMessage.getData().get("custom_data");
}
Now I can send test message from Firebase Console and get a push notification in my phone. I have some queries about generating in-app notification right now. This is my current layout.
I want the push notifications to appear as in-app notifications in my app too. The only class handling the message is MyFirebaseMessagingService class which includes a notificationHelper to help build the notification. How do I pass the message information from MyFirebaseMessagingService to the Notification Fragment I have now? Do I need to store the information in a local file then retrieve the information from the local file to be used in Notification Fragment again? What is the best approach in this case?
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(#NonNull RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
if (remoteMessage.getNotification() != null) {
String title = remoteMessage.getNotification().getTitle();
String body = remoteMessage.getNotification().getBody();
NotificationHelper.displayNotification(getApplicationContext(), title, body);
}
}
}
Another trivial question is about the FCM token issue. I have already created a FCM token. How do I make the app to check if a token has been generated to prevent the token be generated every time I launch the app?
if(instanceIdResult.getToken() == null)
{
//generate token
}
Can I write the code like this?
You can use room database. You save all the notifications and then show them in the fragment. If the fragment is already show, you can send and show instantly with broadcastReceiver. Room
FCM token is created once. The registration token may change when:
The app deletes Instance ID
The app is restored on a new device
The user uninstalls/reinstall the app
The user clears app data.
You can retrieve the current token like this:
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
#Override
public void onComplete(#NonNull Task<InstanceIdResult> task) {
if (!task.isSuccessful()) {
Log.w(TAG, "getInstanceId failed", task.getException());
return;
}
String token = task.getResult().getToken();
}
});
you can use sharedpreferences to store number of notifications you get and when yor app opens show the number on notification and if user read them reset the counter . also you can store the token too
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 :)
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'm using intercom.io to send messages to my customers. I can receive gcm (with notification) from intercom just fine, ONLY if the message that I sent is the first message in a conversation. For subsequent messages in the conversation, I don't receive anything. I put a log in my onMessageReceived() but it didn't receive anything, except if the message is the first message in a conversation.
public class MyGcmListenerService extends GcmListenerService {
#Override
public void onMessageReceived(String from, Bundle data) {
MessageUtils.log("onMessageReceived data is " + data);
}
}
Any idea what am I missing?
In case you don't get what I'm trying to say, here's what I meant:
I select a customer from my intercom.io web dashboard (or
whatever it's called)
Then I click on the 'Message' button to
send a message to the customer.
The customer received my message, together with the notification.
Now I send another message to the customer within the same conversation as before.. but now the customer won't receive any more gcm message from intercom.
Yes it does support now. The github issue is closed now and they added it in 3.0.3
They have a git hub project for FCM, but it is missing few code.
The code is available on this github page and is as follows
if you are extending FirebaseMessagingService in a class in your own app? then you will need to manually pass on the push to intercom now.
private final IntercomPushClient intercomPushClient = new IntercomPushClient();
public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> message = remoteMessage.getData();
if (intercomPushClient.isIntercomPush(message)) {
intercomPushClient.handlePush(getApplication(), message);
} else {
//DO HOST LOGIC HERE
}
}