I am trying to make a chatting app in android studio. All the basic functions are done but I have been struggling with a problem for a time. The problem is sending notification to a device. I have searched the web a lot and was finally successful when a error came by the code is given below.
sendNotification function
private void sendNoti(String senderId, String receiverId){
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("to", "/User/"+receiverId);
JSONObject jsonObject1 = new JSONObject();
jsonObject1.put("title", "Message from " + senderId);
jsonObject1.put("body", "hello");
jsonObject.put("notification", jsonObject1);
JsonObjectRequest request = new JsonObjectRequest(Request.Method.POST, url, jsonObject, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.e("SUCCESS", response + "");
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("ERRORS", error + "");
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> map = new HashMap<>();
map.put("content-type", "application/json");
map.put("authorization", "key=key");
Log.d("Maping",map.toString());
return map;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
int socketTimeout = 1000 * 60;// 60 seconds
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
request.setRetryPolicy(policy);
requestQueue.add(request);
} catch (JSONException e) {
e.printStackTrace();
}
}
MyFirebaseMessagingService
public class MyFirebaseMessagingService extends FirebaseMessagingService {
#Override
public void onMessageReceived(#NonNull #NotNull RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
sendNotification(remoteMessage);
}
#Override
public void onNewToken(String s) {
super.onNewToken(s);
Log.e("newToken", s);
getSharedPreferences("_", MODE_PRIVATE).edit().putString("fb", s).apply();
System.out.println("Token "+s);
}
private void sendNotification(RemoteMessage remoteMessage) {
String user = remoteMessage.getData().get("from");
String title = remoteMessage.getData().get("title");
String body = remoteMessage.getData().get("body");
System.out.println("user "+user);
System.out.println("title "+title);
System.out.println("body "+body);
Intent intent = new Intent(this, MainActivity.class);
String channel_id = "notification_channel";
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder builder = new NotificationCompat
.Builder(getApplicationContext(), channel_id)
.setSmallIcon(R.drawable.vroo)
.setContentTitle(title)
.setContentText("body")
.setAutoCancel(true)
.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000})
.setOnlyAlertOnce(true)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(channel_id, "web_app", NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(notificationChannel);
}
notificationManager.notify(0, builder.build());
}
}
I get the log output that my message is sent but I never receive it on the receiver side can someone please help me?
Related
I want firebase notification badge count. public void onMessageReceived(#NonNull RemoteMessage remoteMessage) { onMessageReceived are notifications coming from firebase. Post_id, title etc. Notifications are coming
` public class MyFirebaseMessageService extends FirebaseMessagingService {
#Override
public void onNewToken(#NonNull String token) {
super.onNewToken(token);
}
#Override
public void onMessageReceived(#NonNull RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
if (remoteMessage.getData().size() > 0) {
Map<String, String> data = remoteMessage.getData();
Log.d("onMessageFirebase: ", remoteMessage.getData().toString());
if (data.get("post_id") != null) {
String _unique_id = data.get("unique_id");
String title = data.get("title");
String message = data.get("message");
String big_image = data.get("big_image");
String link = data.get("link");
String _post_id = data.get("post_id");
assert _unique_id != null;
long unique_id = Long.parseLong(_unique_id);
assert _post_id != null;
long post_id = Long.parseLong(_post_id);
createNotification(unique_id, title, message, big_image, link, post_id);
}
}
}
private void createNotification(long unique_id, String title, String message, String image_url, String link, long post_id) {
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("unique_id", unique_id);
intent.putExtra("post_id", post_id);
intent.putExtra("title", title);
intent.putExtra("link", link);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
String NOTIFICATION_CHANNEL_ID = getApplicationContext().getString(R.string.app_name);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
notificationBuilder.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL)
.setWhen(System.currentTimeMillis())
.setSmallIcon(getNotificationIcon(notificationBuilder))
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.ic_notification_large_icon))
.setContentTitle(title)
.setContentText(message)
.setStyle(new NotificationCompat.BigTextStyle().bigText(message))
.setContentIntent(pendingIntent);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
notificationBuilder.setPriority(Notification.PRIORITY_MAX);
} else {
notificationBuilder.setPriority(NotificationManager.IMPORTANCE_HIGH);
}
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
notificationBuilder.setSound(alarmSound).setVibrate(new long[]{100, 200, 300, 400});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, getString(R.string.app_name), NotificationManager.IMPORTANCE_HIGH);
notificationChannel.enableLights(true);
notificationChannel.shouldShowLights();
notificationChannel.setLightColor(Color.GREEN);
notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
notificationChannel.enableVibration(false);
assert notificationManager != null;
notificationManager.createNotificationChannel(notificationChannel);
}
if (image_url != null && !image_url.isEmpty()) {
Bitmap image = fetchBitmap(image_url);
if (image != null) {
notificationBuilder.setStyle(new NotificationCompat.BigPictureStyle().bigPicture(image));
}
}
//assert notificationManager != null;
notificationManager.notify((int) post_id, notificationBuilder.build());
}
private int getNotificationIcon(NotificationCompat.Builder notificationBuilder) {
notificationBuilder.setColor(ContextCompat.getColor(getApplicationContext(), R.color.colorPrimary));
return R.drawable.ic_stat_onesignal_default;
}
private Bitmap fetchBitmap(String src) {
try {
if (src != null) {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.setConnectTimeout(1200000);
connection.setReadTimeout(1200000);
connection.connect();
InputStream input = connection.getInputStream();
return BitmapFactory.decodeStream(input);
}
} catch (IOException ex) {
ex.printStackTrace();
}
return null;
}
}
How to counter firebase notification badge android
I am trying to make a custom incoming call notification like WhatsApp for my app if I don't use this custom layout then my notification is working. I am trying this for the first time any help will be appreciated.
This is my FireBaseMessagingService Class
public class MyFireBaseMessagingService extends FirebaseMessagingService {
private String CHANNEL_ID = "channel-02";
private String CHANNEL_NAME = "Channel Ring";
long[] pattern = {500, 500, 500, 500, 500, 500, 500, 500, 500};
#Override
public void onNewToken(#NonNull String s) {
super.onNewToken(s);
Log.e("NewToken", s);
getSharedPreferences("_", MODE_PRIVATE).edit().putString("fb", s).apply();
}
#RequiresApi(api = Build.VERSION_CODES.P)
#Override
public void onMessageReceived(#NonNull RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
Log.e("Notification", remoteMessage.getFrom());
showSimpleNotification(getApplicationContext(), remoteMessage, remoteMessage.getData().get("title"), remoteMessage.getData().get("body"));
}
public static String getToken(Context context) {
return context.getSharedPreferences("_", MODE_PRIVATE).getString("fb", "empty");
}
#SuppressLint("RemoteViewLayout")
#RequiresApi(api = Build.VERSION_CODES.P)
public void showFullScreenIntent(RemoteMessage remoteMessage, String title, String body) {
Intent receiveCallIntent = new Intent(getApplicationContext(), FCMReceiver.class);
receiveCallIntent.putExtra("appointment_id", remoteMessage.getData().get("appointment_id"));
receiveCallIntent.putExtra("message", title);
receiveCallIntent.setAction("RECEIVE_CALL");
Intent cancelCallIntent = new Intent(getApplicationContext(), FCMReceiver.class);
receiveCallIntent.putExtra("appointment_id", remoteMessage.getData().get("appointment_id"));
receiveCallIntent.putExtra("message", "Call Rejected");
receiveCallIntent.setAction("CANCEL_CALL");
PendingIntent receiveCallPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1200,
receiveCallIntent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent cancelCallPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1201,
cancelCallIntent, PendingIntent.FLAG_CANCEL_CURRENT);
Uri ringtone = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.custom_call_notification);
remoteViews.setImageViewResource(R.id.caller_image, R.drawable.icon);
remoteViews.setTextViewText(R.id.caller_name, body);
remoteViews.setTextViewText(R.id.call_type, title);
remoteViews.setOnClickPendingIntent(R.id.btnAccept, receiveCallPendingIntent);
remoteViews.setOnClickPendingIntent(R.id.btnDecline, cancelCallPendingIntent);
#SuppressLint("ResourceAsColor") NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID)
.setSmallIcon(R.drawable.icon)
.setStyle(new NotificationCompat.DecoratedCustomViewStyle())
.setCustomContentView(remoteViews)
.setCustomHeadsUpContentView(remoteViews)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setAutoCancel(true)
.setTimeoutAfter(30000)
.setOngoing(true)
.setVibrate(pattern)
.setSound(ringtone)
.setFullScreenIntent(receiveCallPendingIntent, true);
NotificationChannel channel = createChannel();
NotificationManager mNotificationManager = (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
Notification incomingCallNotification = notificationBuilder.build();
mNotificationManager.createNotificationChannel(channel);
mNotificationManager.notify(120, incomingCallNotification);
}
This is my channel
public NotificationChannel createChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_HIGH;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, importance);
channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
channel.setDescription("Call Notifications");
channel.setSound(Uri.parse("android.resource://" + getApplicationContext().getPackageName() + "/" + R.raw.ringtone),
new AudioAttributes.Builder().setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setLegacyStreamType(AudioManager.STREAM_RING)
.setUsage(AudioAttributes.USAGE_VOICE_COMMUNICATION).build());
channel.shouldVibrate();
channel.enableVibration(true);
channel.setVibrationPattern(pattern);
Objects.requireNonNull(getApplicationContext().getSystemService(NotificationManager.class)).createNotificationChannel(channel);
return channel;
}
return null;
}
This is my FCMReceiver Class
public class FCMReceiver extends BroadcastReceiver {
private Context mContext;
private String mTitle;
private String mContent;
String action = "";
#Override
public void onReceive(Context context, Intent intent) {
if (context != null) {
mContext = context;
}
Log.e("Receiver", "Receiver a notification");
mTitle = intent.getStringExtra("message");
if (mTitle != null && !mTitle.isEmpty()) {
Log.e("action", "message : " + mTitle);
performActionClicks(context, mTitle, intent);
Intent iclose = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
context.sendBroadcast(iclose);
context.stopService(new Intent(context, MyFireBaseMessagingService.class));
}
if (intent.getStringExtra("gcm.notification.title") != null) {
if (intent.getStringExtra("gcm.notification title").equalsIgnoreCase("New Appointment")) {
ActivityManager.RunningAppProcessInfo myProcess = new ActivityManager.RunningAppProcessInfo();
ActivityManager.getMyMemoryState(myProcess);
boolean isInBackground = myProcess.importance != ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
if (isInBackground) {
Intent launchIntent = new Intent(context, HomeActivity.class);
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
launchIntent.putExtra("appointment_id", intent.getStringExtra("appointment_id"));
}
}
}
if (intent.getStringExtra("notification") != null) {
}
}
private void performActionClicks(Context context, #NonNull String mTitle, Intent intent) {
if (!mTitle.isEmpty()) {
if (mTitle.equalsIgnoreCase("Ringing")) {
Intent intentCallReceive = new Intent(context, VideoChatViewActivity.class)
.putExtra("appointment_id", intent.getStringExtra("appointment_id"));
intentCallReceive.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
mContext.startActivity(intentCallReceive);
NotificationManagerCompat.from(mContext).cancel(null, 120);
} else if (mTitle.equalsIgnoreCase("Declined")) {
} else if (mTitle.equalsIgnoreCase("Call Rejected")) {
NotificationManagerCompat.from(mContext).cancel(null, 120);
}
}
}
In you NotificationBuilder you need to set notification category to NotificationCompat.CATEGORY_CALL and style to NotificationCompat.BigTextStyle() like this
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID)
.setSmallIcon(R.drawable.icon)
.setStyle(new NotificationCompat.DecoratedCustomViewStyle())
.setCustomContentView(remoteViews)
.setCustomHeadsUpContentView(remoteViews)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setAutoCancel(true)
.setTimeoutAfter(30000)
.setStyle(NotificationCompat.BigTextStyle())
.setCategory(NotificationCompat.CATEGORY_CALL)
.setOngoing(true)
.setVibrate(pattern)
.setSound(ringtone)
.setFullScreenIntent(receiveCallPendingIntent, true);
android fcm notification not received and while the device which supposed to receivethe notification shows this message in Logcat (Received from FCM TITLE: null, Received from FCM BODY: null). I have already checked that notification is not being received in both <26 and >26 SDK Versions
====================MyFirebaseMessagingService===============================
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String channel_id = "the_id";
#Override
public void onNewToken(String s) {
super.onNewToken(s);
Log.e("NEW_TOKEN",s);
updateTokenToFirebase(s);
}
private void updateTokenToFirebase(String token) {
IDrinkShopAPI mService = Common.getAPI();
mService.updateToken("SERVER_01",token,"0")
.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
Log.d("DEBUG_TOKEN",response.body());
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Log.d("DEBUG_TOKEN",t.getMessage());
}
});
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
if(remoteMessage.getData() != null){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
sendNotification26(remoteMessage);
else
sendNotification(remoteMessage);
}
}
private void sendNotification26(RemoteMessage remoteMessage) {
Map<String,String> data = remoteMessage.getData();
String title = data.get("title");
String message = data.get("message");
NotificationHelper helper ;
Notification.Builder builder;
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
helper = new NotificationHelper(this);
builder = helper.getDrinkShopNotification(title,message,defaultSoundUri);
helper.getManager().notify(new Random().nextInt(),builder.build());
}
private void sendNotification(RemoteMessage remoteMessage) {
Map<String,String> data = remoteMessage.getData();
String title = data.get("title");
String message = data.get("message");
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri);
NotificationManager mn =(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
mn.notify(new Random().nextInt(),builder.build());
}
}
=========================NotificationHelper =================================
//this class is used to implement notification for all android versions
public class NotificationHelper extends ContextWrapper {
private static final String CHANNEL_ID = "the_id";
private static final String CHANNEL_NAME = "Drink_Shop";
private NotificationManager notificationManager;
public NotificationHelper(Context base) {
super(base);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
createChannel();
}
#TargetApi(Build.VERSION_CODES.O)
private void createChannel() {
NotificationChannel nc = new NotificationChannel(CHANNEL_ID,CHANNEL_NAME,
NotificationManager.IMPORTANCE_DEFAULT);
nc.enableLights(false);
nc.enableVibration(true);
nc.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
getManager().createNotificationChannel(nc);
}
public NotificationManager getManager() {
if(notificationManager == null)
notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
return notificationManager;
}
#TargetApi(Build.VERSION_CODES.O)
public Notification.Builder getDrinkShopNotification(String title,
String message,
Uri soundUri)
{
return new Notification.Builder(getApplicationContext(),CHANNEL_ID)
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(R.mipmap.ic_launcher)
.setSound(soundUri)
.setChannelId(CHANNEL_ID)
.setAutoCancel(true);
}
}
=============================Manifest=======================================
<service
android:name=".Services.MyFirebaseMessagingService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
============================Build.gradle====================================
implementation 'com.google.firebase:firebase-messaging:20.0.0'
implementation 'com.google.firebase:firebase-core:17.2.1'
implementation 'com.google.android.gms:play-services-auth:17.0.0'
===========================IFCMService=======================================
public interface IFCMService {
#Headers({
"Content-Type:application/json",
"Authorization:mytoken"
})
#POST("fcm/send")
Call<MyResponse> sendNotification(#Body DataMessage body);
}
==========================sendNotificationToServer===============================
// this method used to send the notification to server device
private void sendNotificationToServer(OrderResult orderResult) {
mService.getToken("SERVER_01", "1")
.enqueue(new Callback<Token>() {
#Override
public void onResponse(Call<Token> call, Response<Token> response) {
Map<String,String> contentSend = new HashMap<>();
contentSend.put("title","NEW ORDER");
contentSend.put("message","You have got new order" + orderResult.getOrderId());
DataMessage dataMessage = new DataMessage();
if(response.body().getToken() != null)
dataMessage.setTo(response.body().getToken());
dataMessage.setData(contentSend);
IFCMService ifcmService = Common.getFCMService();
ifcmService.sendNotification(dataMessage)
.enqueue(new Callback<MyResponse>() {
#Override
public void onResponse(Call<MyResponse> call, Response<MyResponse> response) {
if(response.code() == 200){
if(response.body().success == 1){
Toast.makeText(CartActivity.this,
getResources().getString(R.string.order_submitted), Toast.LENGTH_SHORT)
.show();
//Clear Carts From Room Database
Common.cartRepository.emptyCart();
//finish();
}
else {
Toast.makeText(CartActivity.this, "Send Notification Failed", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onFailure(Call<MyResponse> call, Throwable t) {
Toast.makeText(CartActivity.this, ""+t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onFailure(Call<Token> call, Throwable t) {
Toast.makeText(CartActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
I have solved this issue by downgrading firebase-messaging library as follow (implementation 'com.google.firebase:firebase-messaging:17.3.4') as will as .setColor(ContextCompat.getColor(this, R.color.colorAccent)) in NotificationCompat. However this has solved the issue for me for SDK version lower than 26. Anyone knows why it is still cashing on APIs higher than 26 ?! help me please
When the App is running in background the notification is received in the system tray, and when is tapped, the intent is sended to your activity default, with the notification with payload of content of it.
When your application is running in front, the notification is received with the FirebaseMessagingService and the logic that you overrided.
I think you should add the logic of the first point, when the app is running in background
Check here more information
Handling messages
Android fcm notification is being received on android with APIs lower than 26 however APIs 26(Oreo 8.0) it doesn't and it cause app to be crashed
====================MyFirebaseMessagingService===============================
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String channel_id = "the_id";
#Override
public void onNewToken(String s) {
super.onNewToken(s);
Log.e("NEW_TOKEN",s);
updateTokenToFirebase(s);
}
private void updateTokenToFirebase(String token) {
IDrinkShopAPI mService = Common.getAPI();
mService.updateToken("SERVER_01",token,"0")
.enqueue(new Callback<String>() {
#Override
public void onResponse(Call<String> call, Response<String> response) {
Log.d("DEBUG_TOKEN",response.body());
}
#Override
public void onFailure(Call<String> call, Throwable t) {
Log.d("DEBUG_TOKEN",t.getMessage());
}
});
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
if(remoteMessage.getData() != null){
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
sendNotification26(remoteMessage);
else
sendNotification(remoteMessage);
}
}
private void sendNotification26(RemoteMessage remoteMessage) {
Map<String,String> data = remoteMessage.getData();
String title = data.get("title");
String message = data.get("message");
NotificationHelper helper ;
Notification.Builder builder;
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
helper = new NotificationHelper(this);
builder = helper.getDrinkShopNotification(title,message,defaultSoundUri);
helper.getManager().notify(new Random().nextInt(),builder.build());
}
private void sendNotification(RemoteMessage remoteMessage) {
Map<String,String> data = remoteMessage.getData();
String title = data.get("title");
String message = data.get("message");
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(message)
.setAutoCancel(true)
.setColor(ContextCompat.getColor(this, R.color.colorAccent))
.setSound(defaultSoundUri);
NotificationManager mn =(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
mn.notify(new Random().nextInt(),builder.build());
}
}
=========================NotificationHelper =================================
//this class is used to implement notification for APIs 26+
public class NotificationHelper extends ContextWrapper {
private static final String CHANNEL_ID = "the_id";
private static final String CHANNEL_NAME = "Drink_Shop";
private NotificationManager notificationManager;
public NotificationHelper(Context base) {
super(base);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
createChannel();
}
#TargetApi(Build.VERSION_CODES.O)
private void createChannel() {
NotificationChannel nc = new NotificationChannel(CHANNEL_ID,CHANNEL_NAME,
NotificationManager.IMPORTANCE_DEFAULT);
nc.enableLights(false);
nc.enableVibration(true);
nc.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
getManager().createNotificationChannel(nc);
}
public NotificationManager getManager() {
if(notificationManager == null)
notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
return notificationManager;
}
#TargetApi(Build.VERSION_CODES.O)
public Notification.Builder getDrinkShopNotification(String title,
String message,
Uri soundUri)
{
return new Notification.Builder(getApplicationContext(),CHANNEL_ID)
.setContentTitle(title)
.setContentText(message)
.setSmallIcon(R.mipmap.ic_launcher)
.setSound(soundUri)
.setChannelId(CHANNEL_ID)
.setColor(ContextCompat.getColor(this, R.color.colorAccent))
.setAutoCancel(true);
}
}
=============================Manifest=======================================
<service
android:name=".Services.MyFirebaseMessagingService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
============================Build.gradle====================================
implementation 'com.google.firebase:firebase-messaging:20.0.0'
implementation 'com.google.firebase:firebase-core:17.2.1'
implementation 'com.google.android.gms:play-services-auth:17.0.0'
===========================IFCMService=======================================
public interface IFCMService {
#Headers({
"Content-Type:application/json",
"Authorization:mytoken"
})
#POST("fcm/send")
Call<MyResponse> sendNotification(#Body DataMessage body);
}
==========================sendNotificationToServer===============================
// this method used to send the notification to server app
private void sendNotificationToServer(OrderResult orderResult) {
mService.getToken("SERVER_01", "1")
.enqueue(new Callback<Token>() {
#Override
public void onResponse(Call<Token> call, Response<Token> response) {
Map<String,String> contentSend = new HashMap<>();
contentSend.put("title","NEW ORDER");
contentSend.put("message","You have got new order" + orderResult.getOrderId());
DataMessage dataMessage = new DataMessage();
if(response.body().getToken() != null)
dataMessage.setTo(response.body().getToken());
dataMessage.setData(contentSend);
IFCMService ifcmService = Common.getFCMService();
ifcmService.sendNotification(dataMessage)
.enqueue(new Callback<MyResponse>() {
#Override
public void onResponse(Call<MyResponse> call, Response<MyResponse> response) {
if(response.code() == 200){
if(response.body().success == 1){
Toast.makeText(CartActivity.this,
getResources().getString(R.string.order_submitted), Toast.LENGTH_SHORT)
.show();
//Clear Carts From Room Database
Common.cartRepository.emptyCart();
//finish();
}
else {
Toast.makeText(CartActivity.this, "Send Notification Failed", Toast.LENGTH_SHORT).show();
}
}
}
#Override
public void onFailure(Call<MyResponse> call, Throwable t) {
Toast.makeText(CartActivity.this, ""+t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onFailure(Call<Token> call, Throwable t) {
Toast.makeText(CartActivity.this, t.getMessage(), Toast.LENGTH_SHORT).show();
}
});
}
I think you are making the code unnecessarily complicated.
Try this below code
private void createNotification(String title, String message) {
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// only create notification channel if SDK >= 26
if (android.os.Build.VERSION.SDK_INT >= 26) {
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
channel.enableLights(false);
channel.enableVibration(true);
channel.setDescription(CHANNEL_DESC);
manager.createNotificationChannel(channel);
}
Uri defaultSoundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(android.R.drawable.stat_notify_more)
.setContentTitle(title)
.setSmallIcon(R.mipmap.ic_launcher)
.setSound(defaultSoundUri)
.setColor(ContextCompat.getColor(this, R.color.colorAccent))
.setContentText(message);
manager.notify(new Random().nextInt(), builder.build());
}
I have a chat app and I'm trying to display a notification to the user once a new message is received.
Once I launch the activity I call onStart as follows:
#Override
protected void onStart() {
super.onStart();
popNotification();
}
popNotification is a class that is called in order to check if there was any update in my database. If yes, I call another class called AddNotification()
public void popNotification() {
db.collection("Users").document(auth.getUid()).collection("MyChats")
.addSnapshotListener(new EventListener<QuerySnapshot>() {
#Override
public void onEvent(#Nullable QuerySnapshot value,
#Nullable FirebaseFirestoreException e) {
if (e != null) {
Log.w("", "Listen failed.", e);
return;
}
for (QueryDocumentSnapshot doc : value) {
if (doc.getId() != null) {
DocumentReference docRef = db.collection("Users").document(auth.getUid()).collection("MyChats").document(doc.getId());
docRef.get().addOnCompleteListener(new OnCompleteListener<DocumentSnapshot>() {
#Override
public void onComplete(#NonNull Task<DocumentSnapshot> task) {
if (task.isSuccessful()) {
DocumentSnapshot document = task.getResult();
if (document.exists()) {
if(document.getLong("LastMessageTime") > document.getLong("lastChatVisited")){
AddNotification();
}
} else {
Log.d("", "No such document");
}
} else {
Log.d("", "get failed with ", task.getException());
}
}
});
}
}
}
});
}
and AddNotification():
private void AddNotification(){
FirebaseInstanceId.getInstance().getInstanceId()
.addOnCompleteListener(new OnCompleteListener<InstanceIdResult>() {
#Override
public void onComplete(#NonNull Task<InstanceIdResult> task) {
if (!task.isSuccessful()) {
Log.w("", "getInstanceId failed", task.getException());
return;
}
// Get new Instance ID token
String token = task.getResult().getToken();
try {
String title = "TEST ";
MyTaskParams params = new MyTaskParams(token, title, "TTT!");
MyTask myTask = new MyTask();
myTask.execute(params);
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
}
One last thing is the mytask which is:
private class MyTask extends AsyncTask<MyTaskParams, Void, Void> {
#Override
protected Void doInBackground(MyTaskParams... params) {
String userDeviceIdKey = params[0].url;
String title = params[0].title;
String body = params[0].body;
String authKey = "XXX"; // You FCM AUTH key
String FMCurl = "https://fcm.googleapis.com/fcm/send";
URL url;
try {
url = new URL(FMCurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setUseCaches(false);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty("Authorization","key="+authKey);
conn.setRequestProperty("Content-Type","application/json");
JSONObject json = new JSONObject();
json.put("to",userDeviceIdKey);
json.put("priority","high");
JSONObject info = new JSONObject();
info.put("title", title); // Notification title
info.put("body", body); // Notification body
json.put("data", info);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(json.toString());
wr.flush();
conn.getInputStream();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}
Now, the problem is that I don't receive any notification.
I inserted Logs in order to check if the code runs there and it seems to pass all the required functions however still it doesn't show anything.
I added priority = high because I read it might affect but it didn't help.
My message class is:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FCM Service";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Notification Message Body: " + remoteMessage.getData().get("body"));
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "29358305")
.setSmallIcon(R.drawable.ic_launcher_custom_background)
.setContentTitle(remoteMessage.getData().get("title"))
.setContentText(remoteMessage.getData().get("body"))
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(remoteMessage.getData().get("body")))
.setLargeIcon(BitmapFactory.decodeResource(getApplicationContext().getResources(),
R.mipmap.ic_launcher))
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
//createNotificationChannel();
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(235345305, builder.build());
}
}
EDIT:
I also tried to use the following when creating the notification without any improvement:
public class MyFirebaseMessagingService extends FirebaseMessagingService {
private static final String TAG = "FCM Service";
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.d(TAG, "From: " + remoteMessage.getFrom());
Log.d(TAG, "Notification Message Body: " + remoteMessage.getData().get("body"));
createNotificationChannel();
notifyThis(remoteMessage.getData().get("title"),remoteMessage.getData().get("body"));
}
private void createNotificationChannel() {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "ABC";
String description = "ABCDE";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel("191919", name, importance);
channel.setDescription(description);
// Register the channel with the system; you can't change the importance
// or other notification behaviors after this
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
}
public void notifyThis(String title, String message) {
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, "191919")
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentTitle(title)
.setContentText(message)
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
// notificationId is a unique int for each notification that you must define
notificationManager.notify(0, mBuilder.build());
}
Do I also need to add onPause or something else for it to work or do I have some other bug that I cant understand?
Thank you