I am sending following payload for notification:
var message = {
data: {
user: sendData.from,
body: sendData.message,
sentto: sendData.to,
gcm_username: sendData.from
},
android: {
priority: 'high',
notification: {
title: 'Yeni mesaj aldınız',
body: sendData.from + ' size bir mesaj gönderdi',
tag: sendData.from,
sound: 'default',
channelId: 'messages'
}
},
token: deviceToken
};
But sometimes i have to cancel certain notification when user opens the app from the app icon.
I tried following code:
#RequiresApi(api = Build.VERSION_CODES.M)
public Notification deleteNotificationByTag(String senderCode) {
NotificationManager notificationManager = (NotificationManager) mApplication.getSystemService(Context.NOTIFICATION_SERVICE);
StatusBarNotification[] barNotifications = notificationManager.getActiveNotifications();
for(StatusBarNotification notification: barNotifications) {
Log.d(TAG, "getActiveNotification: " + notification.getTag());
if (notification.getTag() != null && notification.getTag().equals(senderCode)) {
notificationManager.cancel(notification.getId());
}
}
return null;
}
But notification.getId() method is always returning 0 value. So cancel is not working. How can i fix it?
You can use the tag to cancel the notification as follows:
public void cancel (String tag, int id);
So even if the id is 0, it should work if the tag is unique.
One option is to send data messages and create notifications with id manually and You can cancel messages as per your requirements.
Related
My notification channel:
CharSequence name = mApplication.getString(R.string.notification_messages_channel);
String description = mApplication.getString(R.string.notification_messages_channel_description);
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel = new NotificationChannel(CHANNEL_MESSAGES, name, importance);
channel.setDescription(description);
channel.enableVibration(true);
channel.enableLights(true);
channel.setVibrationPattern(new long[]{500,100,500});
NotificationManager notificationManager = mApplication.getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
And this is my payload:
var message = {
data: {
user: "asdasd",
body: "adsadasd",
sentto: "asdasd",
gcm_username: "asdda"
},
android: {
priority: 'high',
notification: {
title: 'Yeni mesaj aldınız',
body: 'size bir mesaj gönderdi',
tag: "asd223",
sound: 'default'
}
},
token: deviceToken
};
When a notification arrives to the phone, it plays the notification sound but not vibrating. Where is the problem?
Channel looks set up correctly.
Try adding this directly to NotificationCompat.Builder()
val mBuilder = NotificationCompat.Builder(ctx, "ID")
.setVibrate(arrayOf(100L, 200L).toLongArray())
And make sure, you have your phone set to:
Ok, I found the answer. I added channel information to payload and problem resolved.
New payload:
var message = {
data: {
user: "asdasd",
body: "adsadasd",
sentto: "asdasd",
gcm_username: "asdda"
},
android: {
priority: 'high',
notification: {
title: 'Yeni mesaj aldınız',
body: 'size bir mesaj gönderdi',
tag: "asd223",
sound: 'default',
channel: 'messages'
}
},
token: deviceToken
}
I've set my FCM Cloud Function to priority: "high" but it is still only giving a "default" priority notification (a sound + icon in the system tray).
I want a high priority where there is also a heads up notification like Facebook Messenger. Example below:
Here is my cloud function:
const admin = require('firebase-admin')
admin.initializeApp();
exports.newMatch = functions.https.onCall((data, context) => {
const user1token = data.user1token;
const user2name = data.user2name;
const user2 = data.user2;
const payload = {
notification: {
title: user2name + " says hello!",
body: "Test"
},
data: {
"user2": user2,
}
}
const options = {
priority: "high",
timeToLive: 20000
}
return admin.messaging().sendToDevice(user1token, payload, options);
});
Is it possible to get a heads up notification?
PS: I'm using a Samsung S8 phone.
I am working on an Android app and by using Node.js based function, I'm sending notification to Android and in Android onMessageReceived() function is used to receive data to show notifications. Now the problem, I'm facing is that I want to send some String type data in parallel to Title and Body. What changes should I make?
Here is my Node.js code
'use-strict'
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.firestore.document("Users/{user_id}/Notifications/{notification_id}").onWrite((change,context)=> {
const user_id = context.params.user_id;
const notification_id = context.params.notification_id;
console.log("User ID:"+user_id+" | Notification ID:"+notification_id);
return admin.firestore().collection("Users").doc(user_id).collection("Notifications").doc(notification_id).get().then(queryResult =>{
const from_user_id = queryResult.data().from;
const from_message = queryResult.data().Message;
const from_data = admin.firestore().collection("Users").doc(from_user_id).get();
const to_data = admin.firestore().collection("Users").doc(user_id).get();
return Promise.all([from_data,to_data]).then(result =>{
const from_name = result[0].data().Name;
const to_name = result[1].data().Name;
const token_id = result[1].data().Token_ID;
const payload = {
notification: {
title: "Hey! "+from_name+" here",
body: "Dear "+to_name+", "+from_message+", Will you help me?",
icon: "default"
}
};
return admin.messaging().sendToDevice(token_id,payload).then(result =>{
return console.log("Notification Sent.");
});
});
});
});
And Here is my android code:
public class FirebaseMsgService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
String messageTitle = remoteMessage.getNotification().getTitle();
String messageBody = remoteMessage.getNotification().getBody();
Uri sound = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.enough);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, getString(R.string.default_notification_channel_id))
.setSmallIcon(R.drawable.logo)
.setContentTitle(messageTitle)
.setSound(sound)
.setContentText(messageBody)
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(messageBody))
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
int mNotificationID = (int) System.currentTimeMillis();
NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNotificationManager.notify(mNotificationID,mBuilder.build());
}
}
While I know squad about nodejs (or js in general) I got this working yesterday by passing a data object in the payload.
So, the json request that google makes (I'm using GCM still, but I'm sure FCM would be the same, or very similar payload) looks like this:
{
"to": "<GCM/FCM token>",
"priority": "normal",
"android_channel_id": -99,
"data": {
"title": "Some title",
"body": "Some body",
"more_data_one": "Some more data",
"more_data_two": "Some more data, again!"
}
}
Somehow, however, if I send both data and notification in the payload, the GCMServiceListener never gets called, and the app just displays whatever is in the notification portion of the payload.
By adding the data section (and therefore making the notification a "silent" notification), you are then on charge of intercepting the message, and displaying it with the Notification builder.
I'm working on a cordova application which has a local notification plugin. which I found at this git: https://github.com/katzer/cordova-plugin-local-notifications
I have a problem when I run the click event of a notification. What is happening is the event is being triggered but the parameters notification and status are returning empty.
The notification is triggered and the parameters are correct. the date I used was in the past could it be that?
Does anyone have the same issue and found a solution for it?
cordova.plugins.notification.local.on("click", function (notification, state) {
if (notification.data == null || notification.data == undefined) { }
else if (notification.data.localeCompare('') == 0) {
} else {
}
}, this);
NotificationTemplate = function (sheduleTime, id, title, text, process,rowId) {
var sound = device.platform == 'Android' ? 'file://sound.mp3' : 'file://beep.caf';
cordova.plugins.notification.local.schedule({
id: id,
title: title,
text: text,
at: sheduleTime,
sound: sound,
data: { RowId: rowId, proc: process }
});
};
Check the syntax in your mentioned link. You need to schedule a notification with the required data. The sample demonstrates how to schedule a local notification which repeats every week. The listener will be called when the user has clicked on the local notification.
cordova.plugins.notification.local.schedule({
id: 1,
title: "Production Jour fixe",
text: "Duration 1h",
firstAt: monday_9_am,
every: "week",
sound: "file://sounds/reminder.mp3",
icon: "http://icons.com/?cal_id=1",
data: {meetingId:"123#fg8"}
});
cordova.plugins.notification.local.on("click", function (notification) {
joinMeeting(notification.data.meetingId);
});
I'm trying to use the Firebase Cloud Messaging. I send the notifications from a Node.js server to my apps that are registered to the notification system.
My problem is that on Android 5.1 the notification is "FCM Message" even if I setted the title attribute in the nofitification json. It works fine in Android 6.0. I tried to reboot my device as well.
And this is the code I use to send the notification:
function sendNotificationToUser(userToken, message, onSuccess) {
request({
url: 'https://fcm.googleapis.com/fcm/send',
method: 'POST',
headers: {
'Content-Type' :' application/json',
'Authorization': 'key='+API_KEY
},
body: JSON.stringify({
notification: {
"title": 'My App Name',
"body": message,
"sound": 'default'
},
to : userToken
})
}, function(error, response, body) {
if (error) { console.error(error); }
else if (response.statusCode >= 400) {
console.error('HTTP Error: '+response.statusCode+' - '+response.statusMessage);
}
else {
onSuccess();
}
});
}
As you can see the notification title I send is "My App Name" but on device it shows "FCM Message".
What do I have to do?!
You need to pass the title and then receive it in remoteMessage.getNotification().getTitle() , this will catch title and then display in the top or pass complete JSON from web and receive like this
JSONObject jsonObject = new JSONObject(remoteMessage.getData());
Here is the complete method:
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
// ...
// TODO(developer): Handle FCM messages here.
// Not getting messages here? See why this may be: https://firebase.google.com/support/faq/#fcm-android-background
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());
}
// 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.
}
Ref link
I found that it is a problem related to onMessageReceived callback.
As you can see on the receive a FCM guide
This is expected. (Tested upto Android 10)
FCM has different behaviours for app status (foreground and background / killed).
You should handle this by the payload you sent from server, according to your use case.
The msg sent from server has to be sent in either "notification" or "data" format, from dashboard or server side api.
Note: From firebase dashobard you can only send "notification" body and not data. In such cases, FCM will directly display the notif without giving a callback to your app.
Server side
Below are sample formats :
Notification Type Format
Note : Android System will by default display the notification in the notification tray and you don't need to display it.
{
"to": "your_token_id",
"notification" : {
"title" : "FCM Notification title!",
"body" : "FCM Notification subtext!",
"content_available" : true,
"priority" : "high"
}
}
Data Format (For receiving callback in app, in foreground and background)
Note : You have to handle callback and display notif on your own.
{
"to": "your_token_id",
"data" : {
"title" : "FCM Notification Title ",
"subtext" : "FCM Notification Sub Title",
"type" : "999",
"priority" : "high"
}
}
Android Client
To handle the payload received in your Android receiver, checl the official guide here
override fun onMessageReceived(remoteMessage: RemoteMessage) {
Log.d(TAG, "From: ${remoteMessage.from}")
// Check if message contains a data payload.
remoteMessage.data.isNotEmpty().let {
Log.d(TAG, "Message data payload: " + remoteMessage.data)
if (/* Check if data needs to be processed by long running job */ true) {
// For long-running tasks (10 seconds or more) use WorkManager.
scheduleJob()
} else {
// Handle message within 10 seconds
handleNow()
}
}
// Check if message contains a notification payload.
remoteMessage.notification?.let {
Log.d(TAG, "Message Notification Body: ${it.body}")
}
// 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.
}
Check the documentation here
This is how i get the title from remote messages:
var title = ""
override fun onMessageReceived(remoteMessage: RemoteMessage) {
if (remoteMessage.notification != null) {
title = remoteMessage.notification!!.title!!
}
}
val notificationBuilder = NotificationCompat.Builder(applicationContext, channelId)
.setContentTitle(title)