I'm making a messaging app with Firestore and I want to send notifications when a new message is sent. For this I'm using FCM.
Right now I am declaring 2 payloads: a notification payload and a data payload. When a user sends a message the recipient gets 2 notifications if the app is in the background, and one notification if the app is in the foreground. If I remove the notification payload, the recipient gets one notification whether the app is in the foreground or background.
What I want to happen is that the user receives just one notification when the app is in the background or foreground, and none if the app is in the chat activity with the sender. My understanding is this should be the default behaviour, when I declare both notification and data payloads.
Handle notification messages in a backgrounded app
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.
Can anybody help? I have read this and this but it just doesnt seem to work for me so maybe there is something else I'm not aware of here is my manifest entry
<service
android:name=".MyFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service
android:name=".MyFirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
Here is my cloud function with both notification and data payloads
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp();
exports.notifyNewMessage =
functions.firestore
.document('users/{ID}/contacts/{contactID}/messages/{messageID}')
.onCreate((docSnapshot , context) => {
const message = docSnapshot.data()
const recipientId = message['recipientId']
const senderId = message['sender']
const senderName = message['senderName']
return admin.firestore().doc('users/' + recipientId).get().then(userDoc =>{
const registrationTokens = userDoc.get('registeredToken')
const notificationBody = (message['data_type'] === "TEXT") ?
message['message'] : "You received a new image message."
const payload = {
notification : {
title : senderName + " sent you a message.",
body : notificationBody
},
data : {
TITLE : senderName + " sent you a message.",
BODY : notificationBody,
USER_NAME : senderName,
USER_NUMBER : message['sender'],
CLICK_ACTION : "MessageListActivity",
MESSAGE : message['message'],
}
}
return
admin.messaging().sendToDevice(registrationTokens,payload).then(response
=> {
})
})
})
And here is my messaging service where I send the notification very basic for now
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final int NOTIFICATION_MAX_CHARACTERS = 30;
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// Check if message contains a data payload.
if (remoteMessage.getData().size() > 0) {
Map<String, String> data = remoteMessage.getData();
if (data.size() > 0) {
sendNotification(data);
}
}
// Check if message contains a notification payload.
if (remoteMessage.getNotification() != null) {
}
}
private void sendNotification(Map<String, String> data) {
String author = data.get("USER_NAME");
String title = data.get("TITLE");
String body = data.get("BODY");
String id = data.get("USER_NUMBER");
String message = data.get("MESSAGE");
Intent intent = new Intent(this, MessageListActivity.class);
intent.putExtra(Constants.USER_NAME, author);
intent.putExtra(Constants.USER_NUMBER, id);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
// Create the pending intent to launch the activity
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
if (message.length() > NOTIFICATION_MAX_CHARACTERS) {
message = message.substring(0, NOTIFICATION_MAX_CHARACTERS) +
"\u2026";
}
Uri defaultSoundUri =
RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new
NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_email_black_24dp)
.setContentTitle(String.format(getString(R.string.notification_message),
author))
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */,
notificationBuilder.build());
}
}