Show Notification of Firebase Message onReceived when App is in Background Through api

17,561

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());
    }


}
Share:
17,561
Addi.Star
Author by

Addi.Star

Updated on June 13, 2022

Comments

  • Addi.Star
    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
    Addi.Star over 7 years
    I 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
    Addi.Star over 7 years
    ok i tried yor solution and able to recieve notification from firebase console , but i want to integrate it in my chat class
  • Nahue
    Nahue over 7 years
    What do you want it to do?
  • Addi.Star
    Addi.Star over 7 years
    See 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
    Addi.Star over 7 years
    how 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
    Addi.Star over 7 years
    till 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
    yaircarreno almost 3 years
    NotificationCompat.Builder(this) was was depreciated, you can use NotificationCompat.Builder(this, channelId) instead. At example at github.com/firebase/quickstart-android/blob/…