firebase cloud messaging notification Not Working - android

i'm new to firebase cloud function and fcm, My situation is Whenever a new article is published in the database, I need to show the notification to my app user.
firebase cloud function worked perfectly but notification not received by device android.
cloud function
var functions = require('firebase-functions');
var admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.sendNotification = functions.database.ref('/Vacancy/{articleId}')
.onWrite((event: { after: any; }) => {
console.log("Successfully sent message:2");
var eventSnapshot = event.after;
var str1 = "Author is ";
var str = str1.concat(eventSnapshot.child("author").val());
console.log(str);
var topic = "android";
var payload = {
data: {
title: eventSnapshot.child("title").val(),
author: eventSnapshot.child("author").val()
}
};
return admin.messaging().sendToTopic(topic, payload)
.then(function (response: any) {
console.log("Successfully sent message:", response);
})
.catch(function (error: any) {
console.log("Error sending message:", error);
});
});
manifess code
<service
android:name=".ServiceNotification.NotificationMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
NotificationMessagingService class code
public class NotificationMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
FirebaseMessaging.getInstance().subscribeToTopic("android");
if (remoteMessage.getData().size() > 0) {
showNotification(remoteMessage.getData().get("title"), remoteMessage.getData().get("author"));
}
if (remoteMessage.getNotification() != null) {
}
}
private void showNotification(String title, String author) {
Intent intent = new Intent(this, HomeActivity.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)
.setContentTitle("New Article: " + title)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentText("By " + author)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
cloud function log
1:33:46.257 AM
sendNotification
Successfully sent message:2
1:33:46.263 AM
sendNotification
Author is Raja
1:33:47.022 AM
sendNotification
Successfully sent message: { messageId: 5711725841493019000 }
1:33:47.040 AM
sendNotification
Function execution took 1005 ms, finished with status: 'ok'

Related

Not show push notification (Firebase Cloud Message) on status bar when app is not running

in AndroidManifest.xml
<service
android:name=".CustomFirebaseInstanceIDService"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
<service
android:name=".CustomFirebaseMessagingService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
My service:
import android.util.Log
import com.google.firebase.messaging.FirebaseMessagingService
import com.google.firebase.messaging.RemoteMessage
import org.tokend.template.BuildConfig
class CustomFirebaseMessagingService : FirebaseMessagingService() {
override fun onMessageReceived(remoteMessage: RemoteMessage?) {
if (remoteMessage?.data?.isNotEmpty()!!) {
val payloadData: Map<String, String> = remoteMessage.data
PushNotificationService.showNotification(applicationContext, payloadData["title"]!!, payloadData["body"]!!)
}
// Check if message contains a notification payload.
remoteMessage.notification?.let {
val notificationTitle : String? = it.title
val notificationBody: String? = it.body
PushNotificationService.showNotification(applicationContext, notificationTitle!!, notificationBody!!)
}
}
And show push:
object PushNotificationService {
val TAG = PushNotificationService::class.java.name
val CHANNEL_ID = "channelId"
val NOTIFICATON_ID = 1
fun showNotification(context: Context, title: String, body: String) {
val intent = Intent(context, SignInActivity::class.java).apply {
this.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
val pendingIntent: PendingIntent = PendingIntent.getActivity(context, 0, intent, 0)
val builder = NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(),
R.mipmap.ic_launcher))
.setContentTitle(title)
.setStyle(NotificationCompat.BigTextStyle().bigText(body))
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
// Set the intent that will fire when the user taps the notification
.setContentIntent(pendingIntent)
.setAutoCancel(true)
// Show the notification
with(NotificationManagerCompat.from(context), {
// NOTIFICATON_ID is a unique int for each notification that you must define
this.notify(NOTIFICATON_ID, builder.build())
})
}
So:
when server send data or notification and application is run and foreground then method onMessageReceived success call and success show push notification (title and body) in the status bar (on top)
when server send data or notification and application is run and minimize then method onMessageReceived success call and success show push notification in the status bar (on top)
But when server send data or notification and application is NOT RUNNING then not call method onMessageReceived and also not show push notification on the status bar.
But I need to show push notification on the status bar when app is not running.
I send data message to my android device by Python script:
import firebase_admin, sys
from firebase_admin import credentials, messaging
message = messaging.Message(
data={
"title": "Test data",
"body": "Body of long test text of data test long body message for type data"
},
token=sys.argv[1],
)
response = messaging.send(message)
P.S. If I send message from Firebase console then success show push notification on status bar when app is not running.
Try to only send data payload (without notification payload) it should always call onMessageReceived. Also try adding priority (my .js example):
const payload = {
data: {
title: 'finalTitle',
body: 'message',
},
android:{
priority: 'high'
},
topic: channel
};
admin.messaging().send(payload)

Cancelling firebase notification from app

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.

How to send other data than title and body in Firebase Messaging Service? (Node.js, Android)

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.

Persistent error sending FCM notifications through Firebase Functions

I am trying to send notifications to users in Android Application, written in Java, using Firebase Functions, but I am still getting this error in the Firebase Functions Console Log:
Error: Messaging payload contains an invalid value for the "notification.title" property. Values must be strings.
at FirebaseMessagingError.Error (native)
at FirebaseMessagingError.FirebaseError [as constructor] (/user_code/node_modules/firebase-admin/lib/utils/error.js:25:28)
at new FirebaseMessagingError (/user_code/node_modules/firebase-admin/lib/utils/error.js:130:23)
at /user_code/node_modules/firebase-admin/lib/messaging/messaging.js:486:27
at Array.forEach (native)
at /user_code/node_modules/firebase-admin/lib/messaging/messaging.js:483:32
at Array.forEach (native)
at Messaging.validateMessagingPayload (/user_code/node_modules/firebase-admin/lib/messaging/messaging.js:476:21)
at /user_code/node_modules/firebase-admin/lib/messaging/messaging.js:313:37
at process._tickDomainCallback (internal/process/next_tick.js:135:7)
Here is my Function:
const functions = require('firebase-functions');
const admin = require('firebase-admin');
admin.initializeApp(functions.config().firebase);
exports.pushNotification = functions.database.ref('/messages/send').onWrite(
event => {
console.log('Push notification event triggered');
event.data.adminRef.parent.once('value').then((snapshot) => {
var valueObject = snapshot.val();
const payload = {
notification: {
title: JSON.stringify(valueObject.title),
body: JSON.stringify(valueObject.message),
click_action: ".WebsiteActivityNotification",
sound: "default"
},
data: {
title: JSON.stringify(valueObject.title),
message: JSON.stringify(valueObject.message),
link: JSON.stringify(valueObject.link)
}
};
const options = {
priority: "high",
timeToLive: 60 * 60 * 24 //24 hours
};
return admin.messaging().sendToTopic("notifications", payload, options);
});
});
Here is my Firebase Database structure:
/messages
link: "..."
message: "..."
title: "..."
send: "..."
Here is my Service:
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;
public class FCMService extends FirebaseMessagingService {
private static final String TAG = "MyFirebaseMsgService";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
String notificationTitle = null, notificationBody = null;
String dataTitle = null, dataMessage = null, dataLink = null;
if (remoteMessage.getData().size() > 0) {
Log.d(TAG, "Message data payload: " + remoteMessage.getData().get("message"));
dataTitle = remoteMessage.getData().get("title");
dataMessage = remoteMessage.getData().get("message");
dataLink = remoteMessage.getData().get("link");
}
if (remoteMessage.getNotification() != null) {
Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
notificationTitle = remoteMessage.getNotification().getTitle();
notificationBody = remoteMessage.getNotification().getBody();
}
sendNotification(notificationTitle, notificationBody, dataTitle, dataMessage, dataLink);
}
private void sendNotification(String notificationTitle, String notificationBody, String dataTitle, String dataMessage, String dataLink) {
Intent intent = new Intent(this, WebsiteActivityNotification.class);
intent.putExtra("title", dataTitle);
intent.putExtra("message", dataMessage);
intent.putExtra("link", dataLink);
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.mipmap.ic_launcher)
.setContentTitle(notificationTitle)
.setStyle(new NotificationCompat.BigTextStyle().bigText(notificationBody))
.setContentText(notificationBody)
.setAutoCancel(true)
.setPriority(Notification.PRIORITY_HIGH)
.setDefaults(Notification.FLAG_AUTO_CANCEL | Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
Activity to open tag in Manifest:
<activity
android:name=".WebsiteActivityNotification"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name=".WebsiteActivityNotification" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Services tags in Manifest:
<service android:name=".FCMService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service android:name=".FirebaseIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
And still doesn't work...
Every answer is welcomed. Thank you very much!

FCM notification not reveived on Android

I'm trying to use FCM to send notifications. I'm building an app using Xamarin, so I followed this tutorial to set up my notifications.
Here my firebase service:
[Service]
[IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
public class MyFirebaseIIDService : FirebaseInstanceIdService
{
const string TAG = "MyFirebaseIIDService";
public override void OnTokenRefresh()
{
var refreshedToken = FirebaseInstanceId.Instance.Token;
System.Diagnostics.Debug.WriteLine(TAG, "Refreshed token: " + refreshedToken);
SendRegistrationToServer(refreshedToken);
}
void SendRegistrationToServer(string token)
{
// Add custom implementation, as needed.
}
}
[Service]
[IntentFilter(new[] { "com.google.firebase.MESSAGING_EVENT" })]
public class MyFirebaseMessagingService : FirebaseMessagingService
{
const string TAG = "MyFirebaseMsgService";
public override void OnMessageReceived(RemoteMessage message)
{
Android.Util.Log.Debug(TAG, "From: " + message.From);
Android.Util.Log.Debug(TAG, "Notification Message Body: " + message.GetNotification().Body);
}
void SendNotification(string messageBody)
{
var intent = new Intent(this, typeof(MainActivity));
intent.AddFlags(ActivityFlags.ClearTop);
var pendingIntent = PendingIntent.GetActivity(this, 0 /* Request code */, intent, PendingIntentFlags.OneShot);
var defaultSoundUri = RingtoneManager.GetDefaultUri(RingtoneType.Notification);
var notificationBuilder = new NotificationCompat.Builder(this)
.SetContentTitle("FCM Message")
.SetContentText(messageBody)
.SetAutoCancel(true)
.SetSound(defaultSoundUri)
.SetContentIntent(pendingIntent);
var notificationManager = NotificationManager.FromContext(this);
notificationManager.Notify(0, notificationBuilder.Build());
}
}
I had an issue with the refresh token malfunctioning from time to time so I added this to my MainActivity:
if (IsPlayServicesAvailable())
{
var json = "";
using (StreamReader sr = new StreamReader(Assets.Open("google_services.json")))
{
json = sr.ReadToEnd();
}
var options_from_json = JObject.Parse(json);
try
{
var options = new FirebaseOptions.Builder()
.SetApplicationId(options_from_json["client"][0]["client_info"]["mobilesdk_app_id"].ToString())
.SetApiKey(options_from_json["client"][0]["api_key"][0]["current_key"].ToString())
//.SetDatabaseUrl("Firebase-Database-Url")
.SetGcmSenderId(options_from_json["project_info"]["project_number"].ToString())
.Build();
var firebaseApp = FirebaseApp.InitializeApp(this, options);
}
catch (IllegalStateException e)
{
System.Diagnostics.Debug.WriteLine("L'app firebase existe déjà, donc il n'y a rien à faire.");
}
await Task.Run(() =>
{
var instanceID = FirebaseInstanceId.Instance;
var iid1 = instanceID.Token;
var iid2 = instanceID.GetToken(options_from_json["project_info"]["project_number"].ToString(), Firebase.Messaging.FirebaseMessaging.InstanceIdScope);
System.Diagnostics.Debug.WriteLine("Iid1: {0}, iid2: {1}", iid1, iid2);
});
}
Fine, so far I've got token for emulators as well as real life devices.
My problem is the reception of notification: it's really hazardous, sometime I get some an instant after I hit send on FCM console, sometime I have to reboot the device, sometime it just takes hours to arrive and sometime I just receive nothing... My setup doesn't change and the devices aren't on a wifi.
Any clues?

Categories

Resources