I have implemented FCM in my app and getting notification from the action performed in the app. So if a user likes a post I get a notification like "Someone(name) likes you. if multiple users like the post I get multiple notification exes: User1 likes you, User2 likes you.
I want one notification where it shows the Username of the user + number of other user liked you. How to handle this on client side or do we have to handle it from server side. Any ideas?
Firebase cloud messaging will let you send messages to your users in real time. I suggest you read about it from the official google documentation, then implement it so that when someone likes your post, your server is able to send a JSON message to activate Firebase Cloud Messaging.
There are two forms of notification:
Notification messages, sometimes thought of as “display messages.”
These are handled by the FCM (firebase cloud messaging) SDK
automatically.
Data messages, which are handled by the client app.
Step one: Add the FCM SDK API to your project
Step two Create a service that can receive your data message
<service
android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "myTag";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
}
}
Step three: Create your notification from that service
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.notification_icon)
.setContentTitle("Someone liked your post")
.setContentText("Accept this answer if it is useful!");
Step four: Handle any "likes" on your server side by sending a JSON request to your Android app with the notification:
{
"message":{
"token":"bk3RNwTe3H0:CI2k_HHwgIpoDKCIZvvDMExUdFQ3P1...", //this specefies the device
"notification":{
"title":"Someone liked your post",
"body":"col"
}
"data": {
"Nick" : "Mario",
"Room" : "PortugalVSDenmark"
}
"android":{
"ttl":"86400s",
"notification"{
"click_action":"OPEN_ACTIVITY_1"
}
},
}
}
More about Firebase Cloud Messaging on my blog.
Related
I'm using Firebase Cloud Messaging to send notifications and ShortcutBadger to update the unread messages count on our app badge. I've extended the FirebaseMessagingService class and implemented the override method onMessageReceived, which seems to be working fine since I get notifications when my app is in the background or killed. However, when I add the ShortcutBadger call inside this method, I no longer receive notifications and the ShortcutBadger call does not work.
ShortcutBadger requires a Context and, since FirebaseMessagingService extends Service, it is a context, which is why I simply pass this. I also have ShortcutBadger working in other parts of my code, so I know it works.
Any suggestions would be appreciated.
public class Notifications extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
ShortcutBadger.applyCount(getApplicationContext(), 1); // <-- now is working
}
}
EDIT: SERVER SIDE CODE
Here's the server-side code that sends the Firebase message.
Notification notification = new Notification.Builder(null)
.title(msg.getTitle())
.badge(msg.getBadge())
.body(msg.getMessage())
.build();
Message message = new Message.Builder()
.timeToLive(timeToLive)
.delayWhileIdle(true)
.notification(notification)
.addData("text", msg.getMessage())
.addData("title", msg.getTitle())
.addData("line1", msg.getSubtitle())
.addData("badge", String.valueOf(msg.getBadge()))
.addData("qummute_notification", "true")
.build();
Result result = send(message, deviceKey, retries);
It's been suggested that I send the message without the Notification payload. Will try that and see what happens.
Have you made sure that you are not calling ShortcutBadger.removeCount(Context context) while testing?
Try using ShortcutBadger.applyCountOrThrow(Context context, int badgeCount) to see if any exceptions are thrown.
The onMessageReceived(RemoteMessage remoteMessage) is called on a background thread. Perhaps the phone/launcher you are testing on is using a badge that cannot be created and shown from a background thread.
You need to handle this situation from server side.Remove Notification from your JSON and Use data.
Remove Notification Hole object,
"notification": {
"title": "My Title if any",
"body": "location",
"sound": "default"
},
From where you are sending the notification you need to change that code,
For Server side code should be like below then your onMessageReceived method call even if app is in the background or killed.
{
"registration_ids": [
"cBbGxlj5JRI:APA91bFRLp3tDoBo_P5lGYGUZ4F6iJ55yBJq4GInL7RVV2asHR5PovqnMX-ekIdl_xOYyRyJmSe3SkxYMa3mzIvqml3MmLYZUh8JWygixIebhzhb_l4xv0Q-v3werKl_UO069G1uOyvq"
],
"data": {
"title": "alt_ctgry - Vehicle Number - extra detail(if any)",
"body": "location"
},
"priority": "high"
}
if you want to create notification then write your own code for notification.
For Notification data access use below code,
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
Log.e("FCM", "Call onMessageReceived\n" + remoteMessage + "");
String title = remoteMessage.getData().get("title");
String body = remoteMessage.getData().get("body");
createNotification(title, body);
}
which seems to be working fine since I get notifications when my app is in the background or killed
No, onMessageReceived is called when your app in foreground but not background IF you have notification payload.
In your server side code you add notification payload, so previously your onMessageReceived also was not called when app in background but notification was shown by OS from your payload.
If you want to handle your push all the time you need to remove notification payload, but remember that it could break pushes on iOS if you have an iOS app.
I'm trying to send push notifications throught FCM services.
In my MainActivity I write this code:
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();
}
}
};
In order to subscribe user to a topic.
From backend I make a call to FCM service at this link : https://fcm.googleapis.com/fcm/send
in which I pass this JSON:
{
"to":"/topics/global",
"data":{
"title":"test",
"is_background":false,
"message":"testmessage",
"image":"",
"payload":{
"team":"Test",
"score":"5.6"
},
"timestamp":"2017-05-23 11:55:35"
}
}
and I get this response:
{\"message_id\":8863205901902209389}
But my device doesn't show any notifaction, exept if I use Firebase console with "user segment" or "single device" . Also in Firebase console doesn't works "topic" way.
Thank you in advance for any response.
There are two types of FCM messages.
Notification Messages
Data Messages
On the client side, Notification messages are handled by FCM and automatically displayed in the notification window. If you are using Data Messages, your app needs to handle the received message and create a notification.
The sample payload in your question is a data message and hence it is not displayed in notification (I assume you didn't do any handling). The notifications sent via FCM console are always notification messages and hence those are automatically displayed.
Refer to this FCM page for more details on this.
We require FCM with image,title, and description in notification drawer if app is not in foreground we have try by sending following notification request :
{"priority" : "high",
"to": "/topics/movies",
"data": {
"image":"image ur",
"title":"App name",
"text":"Image with Text"
},"notification":{"title":"App Name","body":"description"}
}
But, in android if app is in background then on messge receive not called however if app is in foreground then notification will generate with image and title
#Override
public void onMessageReceived(final RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
Log.d("onMessageReceived-->", "getData ->" + remoteMessage.getData());
}
However if we send by removing notification key then android work if app is in background or foreground. but iOS did not receive if we remove notification key.
Please help us and Thanks in advance.
When app is in background, the notification message is deliver by Notification, when the notification is tap, app is launch, how can i get the message body?
the intent is this:
Bundle[{google.sent_time=1470813025421, from=568540028909,
google.message_id=0:1470813025865549%31bd1c9631bd1c96,
collapse_key=com.google.firebase.quickstart.fcm}]
no message body in intent, only message id!
Thanks!
try this
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// TODO(developer): Handle FCM messages here.
// If the application is in the foreground handle both data and notification messages here.
// 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.
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "From: " + remoteMessage.getData().get("message"));
// Log.d(TAG, "Notification Message Body: " + remoteMessage.getNotification().getBody());
// if you sending data with custom key
Log.d(TAG, "Notification Message of custom key: " +remoteMessage.getData().get("your key"));
sendNotification(remoteMessage.getData().get("message"));
}
I am sorry but what you are trying to do is not possible.
Currently it's not possible to access the (body, title, icon ...) information of a
notification-message from the activity that is launched when the notification is opened.
You can instead access the data component of the notification message.
One possible alternative is to use data-message messages and create your own custom notification and custom logic.
see notification-message vs data-message here:
https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages
PS: if would be useful if you could report a Feature Request through the firebase support page.
In this way the team can correctly prioritize future features.
https://firebase.google.com/support/contact/bugs-features/
With the Urban airship's library, I was able to implement the push notification ok. Which will trigger the onReceive() method every time I send push a message from a server.
But when I switch to use PushRich notification, whenever I send out a rich message, it won't triiger the onReceive() method.
I want to be able to achieve the same way it dose with the push notification in here.
I tried the richpush simple code from the website, but it seems to be having the same problem.
The fact that I think its possible its because from the sample code onReceive() method has the following code in it.
// Ignore any non rich push notifications
if (!RichPushManager.isRichPushMessage(intent.getExtras())) {
return;
}
Would it mean, it should send intent when we send rich push from server ?
Problem has been solved. After more digging into the Urban airship library. The rich message that contains HTML is actually be put into part of the push message JSON object.
Looks like such in a simple push message
{
"audience" : { "tag" : [ "tag1", "tag2" ] },
"device_types" : [ "ios" ],
"notification" : { "alert" : "New message!" },
"message" : {
"title" : "Message title",
"body" : "<Your message here>",
"content_type" : "text/html"
}
}
The "message" object is actually the Rich message itself. So therefore, catching the intent for a simple push message can from then determine if a rich message exist in the intent.