Show Notification of Firebase Message onReceived when App is in Background Through api
Solution 1
I solved this problem may it help someone ,
In order to send Notification of firebase through api to single device is as follows:
1: generate Instance Id , unique for every device
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private static final String TAG = "MyFirebaseIIDService";
@Override
public void onTokenRefresh() {
//Getting registration token
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
//Displaying token on logcat
Log.d(TAG, "Refreshed token: " + refreshedToken);
sendRegistrationToServer(refreshedToken);
}
private void sendRegistrationToServer(String token) {
//You can implement this method to store the token on your server
//Not required for current project
}
}
Note: you can call Instance Id from any where in your Application Like this:
String tkn = FirebaseInstanceId.getInstance().getToken();
Toast.makeText(Doc_users.this, "Current token ["+tkn+"]",
Toast.LENGTH_LONG).show();
Log.d("App", "Token ["+tkn+"]");
this token must be used to send notification to single device it is the id of the device you can store it in your firebase database
reference.child(UserDetails.username).child("token").setValue(tokun);
2:Now You can build your logic to fetch these ids and build your request
public static String makeRequest(String id) throws JSONException {
HttpURLConnection urlConnection;
JSONObject json = new JSONObject();
JSONObject info = new JSONObject();
info.put("title", "Notification Title"); // Notification title
info.put("body", "Notification body"); // Notification body
info.put("sound", "mySound"); // Notification sound
json.put("notification", info);
json.put("to","INSTANCE ID FETCHED FOR SIGNLE DEVICE HERE");
Log.e("deviceidkey==> ",id+"");
Log.e("jsonn==> ",json.toString());
String data = json.toString();
String result = null;
try {
//Connect
urlConnection = (HttpURLConnection) ((new URL("https://fcm.googleapis.com/fcm/send").openConnection()));
urlConnection.setDoOutput(true);
urlConnection.setRequestProperty("Content-Type", "application/json");
urlConnection.setRequestProperty("Authorization", "key=YOUR FIREBASE SERVER KEY");
urlConnection.setRequestMethod("POST");
urlConnection.connect();
//Write
OutputStream outputStream = urlConnection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
writer.write(data);
writer.close();
outputStream.close();
//Read
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream(), "UTF-8"));
String line = null;
StringBuilder sb = new StringBuilder();
while ((line = bufferedReader.readLine()) != null) {
sb.append(line);
}
bufferedReader.close();
result = sb.toString();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
Notification will generate on that single device sent from your device you can debug to put your own device key and use postman for valid request: Good Luck
Solution 2
You need a service running on background to catch the PUSH notification and show it to the user, and that's what the Firebase Notification Service provides you with. I have this one (you'll have to modify it in order to do what you want to do when a notification is showed up):
public class MyFirebaseMessagingService extends FirebaseMessagingService {
@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
if (remoteMessage.getNotification().getBody() != null) {
Log.e("FIREBASE", "Message Notification Body: " + remoteMessage.getNotification().getBody());
sendNotification(remoteMessage);
}
}
private void sendNotification(RemoteMessage remoteMessage) {
RemoteMessage.Notification notification = remoteMessage.getNotification();
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.logo_gris))
.setSmallIcon(R.drawable.logo_gris)
.setContentTitle(notification.getTitle())
.setContentText(notification.getBody())
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
}
Addi.Star
Updated on June 13, 2022Comments
-
Addi.Star almost 2 years
I have built a chat application . It is working fine . both users can chat easily but where I get Stuck is if one user's app is at background and screen is off , user is unable to be notified of that received message.
What I want now is in my application is when userA sends message to userB , and userB mobile is idle but application is running in background, userB can get notification about that message. and userB can open the chat activity and read the message .
My firebase notification is working from firebase console but I don't know how to call instance id and send that to particular device from api and particular user get notification about the received message , when application screen is off and application is running in background state . How should I achieve it?
I have my firebase instance id service class here:
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService { private static final String TAG = "MyFirebaseIIDService"; @Override public void onTokenRefresh() { //Getting registration token String refreshedToken = FirebaseInstanceId.getInstance().getToken(); //Displaying token on logcat Log.d(TAG, "Refreshed token: " + refreshedToken); } private void sendRegistrationToServer(String token) { //You can implement this method to store the token on your server //Not required for current project } }
Here is my MyFirebase Messaging Service Class
public class MyFirebaseMessagingService extends FirebaseMessagingService { @Override public void onMessageReceived(RemoteMessage remoteMessage) { if (remoteMessage.getNotification().getBody() != null) { Log.e("FIREBASE", "Message Notification Body: " + remoteMessage.getNotification().getBody()); sendNotification(remoteMessage); } } private void sendNotification(RemoteMessage remoteMessage) { RemoteMessage.Notification notification = remoteMessage.getNotification(); Intent intent = new Intent(this, LoggedInView.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_ONE_SHOT); Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.first_aid)) .setSmallIcon(R.drawable.first_aid) .setContentTitle(notification.getTitle()) .setContentText(notification.getBody()) .setAutoCancel(true) .setSound(defaultSoundUri) .setContentIntent(pendingIntent); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(0, notificationBuilder.build()); } }
Here is my chat Activity:
public class Chat extends AppCompatActivity { LinearLayout layout; ImageView sendButton,vidcall; EditText messageArea; ScrollView scrollView; Firebase reference1, reference2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.act_chat); layout = (LinearLayout)findViewById(R.id.layout1); sendButton = (ImageView)findViewById(R.id.sendButton); vidcall = (ImageView)findViewById(R.id.vidBtnk); messageArea = (EditText)findViewById(R.id.messageArea); scrollView = (ScrollView)findViewById(R.id.scrollView); Firebase.setAndroidContext(this); reference1 = new Firebase("https://*******.firebaseio.com/messages/" + UserDetails.username + "_" + UserDetails.chatWith); reference2 = new Firebase("https://*******.firebaseio.com/messages/" + UserDetails.chatWith + "_" + UserDetails.username); sendButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { String messageText = messageArea.getText().toString(); if(!messageText.equals("")){ Map<String, String> map = new HashMap<String, String>(); map.put("message", messageText); map.put("user", UserDetails.username); reference1.push().setValue(map); reference2.push().setValue(map); } messageArea.setText(""); } }); vidcall.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startActivity(new Intent(Chat.this, ConnectActivity.class)); } }); reference1.addChildEventListener(new ChildEventListener() { @Override public void onChildAdded(DataSnapshot dataSnapshot, String s) { Map map = dataSnapshot.getValue(Map.class); String message = map.get("message").toString(); String userName = map.get("user").toString(); if(userName.equals(UserDetails.username)){ addMessageBox("You:-\n" + message, 1); } else{ addMessageBox(UserDetails.chatWith + ":-\n" + message, 2); } } @Override public void onChildChanged(DataSnapshot dataSnapshot, String s) { } @Override public void onChildRemoved(DataSnapshot dataSnapshot) { } @Override public void onChildMoved(DataSnapshot dataSnapshot, String s) { } @Override public void onCancelled(FirebaseError firebaseError) { } }); } // boolean doubleBackToExitPressedOnce = false; @Override public void onBackPressed() { AlertDialog.Builder builder1 = new AlertDialog.Builder(Chat.this); builder1.setMessage("CAUTION! -> Do Wish to End this Session"); builder1.setCancelable(true); builder1.setPositiveButton( "Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { finish(); dialog.cancel(); } }); builder1.setNegativeButton( "No", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }); AlertDialog alert11 = builder1.create(); alert11.show(); } public void addMessageBox(String message, int type){ TextView textView = new TextView(Chat.this); textView.setText(message); LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); lp.setMargins(0, 0, 0, 10); textView.setLayoutParams(lp); if(type == 1) { textView.setBackgroundResource(R.drawable.rounded_corner1); } else{ textView.setBackgroundResource(R.drawable.rounded_corner2); } layout.addView(textView); scrollView.fullScroll(View.FOCUS_DOWN); } }
-
Addi.Star over 7 yearsI have no idea how to integrate firebase notification service into my current running chat application , can you provide any complete example or tutorial .
-
Addi.Star over 7 yearsok i tried yor solution and able to recieve notification from firebase console , but i want to integrate it in my chat class
-
Nahue over 7 yearsWhat do you want it to do?
-
Addi.Star over 7 yearsSee my chat.java class . In this class i send/recieve text messages . now when one user mobile screen is off or application is in background . user should get notified about the incoming message and so that one can click open it to read the message .
-
Addi.Star over 7 yearshow should i call notification from api and send it to particular user and detect weather the application screen is off and app is in background
-
Addi.Star over 7 yearstill now i know that instance id token is used to send firebase notification for particular user device . and with that token we can build mechanism for notification from api . but i didn't found any working example or tutorial to integrate it in my chat.java class
-
yaircarreno almost 3 yearsNotificationCompat.Builder(this) was was depreciated, you can use NotificationCompat.Builder(this, channelId) instead. At example at github.com/firebase/quickstart-android/blob/…