Sending push notification from android is nothing but a post request .

PreRequirements:
1. FireBase Developer account
2. Your Project Connected to Fire base
3. FireBase Token of person to whom you want to send notification .
4. Firebase Legacy server key

I will be skipping first 3 , there are hundreds of tutorials out there ,if you still have any problem in first 3 steps please do comment below or contact me .

4. Getting your Firebase Legacy server key 

a. Open your project on fire base
b. Click on settings icon on top ( beside overview )
c. Click on project settings
firebase project settings
d. Click on cloud messaging  and copy your Legacy server key ,it generally starts              with Alza…………………(Be careful do not give this key to any one)

firebase legacy server key

hope you have every thing ready now , first i will tell the procedure then how to do it
as i mentioned above sending a push notification is nothing but a post request these are the following things you need to know

URL: https://fcm.googleapis.com/fcm/send

Method Type: POST

Headers:

Content-Type: application/json
Authorization: key="Firebase Legacy server key" 

Body/Payload : See this for more info

{
  "to" : "Receiver FireBase token",  // if you want to send to all use to : "/topics/all" 
  "priority" : "normal",                   //optional
  "notification" : {
    "body" : "This week's edition is now available.",
    "title" : "NewsMagazine.com",
    "icon" : "new"
  },
  "data" : {
    "key1" : "value1",
    "key2" : "value2"  // you can send any number of key value pairs here
  }
}

I would suggest you not to send any data in notification part because your  push notifications will behave differently when app is in foreground and background . Keep body and title inside the data part itself .

Recommended Body/Payload:

{   "to" : "Receiver FireBase token", // if you want to send to all use to : "/topics/all"
    "priority" : "normal", //optional  
    "data" : {    
                 "title" : "your notification title"
                 "body" : "yournotification body/message"
                 "key1" : "value1",  
                 "key2" : "value2" // send any thing else needed for your app here  
             } 
}

Implementation :

Here is the snippet of my implementation using Volley library.

JSONObject json = new JSONObject();
 try {
 JSONObject userData=new JSONObject();
 userData.put("title","your title");
 userData.put("body","your body");

json.put("data",userData);
json.put("to", receiverFirebaseToken);
 }
 catch (JSONException e) {
 e.printStackTrace();
 }
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest("https://fcm.googleapis.com/fcm/send", json, new Response.Listener<JSONObject>() {
 @Override
 public void onResponse(JSONObject response) {

Log.i("onResponse", "" + response.toString());
 }
 }, new Response.ErrorListener() {
 @Override
 public void onErrorResponse(VolleyError error) {

}
 }) {
 @Override
 public Map<String, String> getHeaders() throws AuthFailureError {

Map<String, String> params = new HashMap<String, String>();
 params.put("Authorization", "key=" + SERVER_API_KEY);
 params.put("Content-Type", "application/json");
 return params;
 }
 };
 MySingleton.getInstance(context).addToRequestQueue(jsonObjectRequest);

That is it for sender part , now for  receiving notification we need to write a service which extends FirebaseMessagingService . Do not forget to implement firebase messaging dependency

compile 'com.google.firebase:firebase-messaging:11.2.0'

// use latest version of  dependency above check here

public class MyFirebaseMessagingService extends FirebaseMessagingService {

private String TAG = "Message Service";

@Override
 public void onMessageReceived(RemoteMessage remoteMessage) {

if (remoteMessage.getData().size() > 0) {
 Log.d(TAG, "Message data payload: " + remoteMessage.getData());
 String tile=remoteMessage.getData().get("title");
 String body=remoteMessage.getData().get("body");

sendNotification( title , body);

if (/* Check if data needs to be processed by long running job */ true) {
 // For long-running tasks (10 seconds or more) use Firebase Job Dispatcher.
 // scheduleJob();

} else {
 // Handle message within 10 seconds
 // handleNow();
 }
}
super.onMessageReceived(remoteMessage);
 }

private void sendNotification(String title, String messageBody) {
 Intent intent = new Intent(this, ChatActivity.class); // class which has to be redirected when user clicks notification
 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 = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
 .setSmallIcon(R.drawable.ic_stat_chat) // your drawable for notification icon
 .setContentTitle(title)
 .setContentText(messageBody)
 .setAutoCancel(true)
 .setSound(defaultSoundUri)
 .setContentIntent(pendingIntent);

NotificationManager notificationManager =
 (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, notificationBuilder.build());
}
}

don’t forget to add this service in AndroidManifest.xml

 <service
 android:name=".MyFirebaseMessagingService">
 <intent-filter>
 <action android:name="com.google.firebase.MESSAGING_EVENT"/>
 </intent-filter>
 </service>

That’s it , now you should be able to send,receive and handle notification.

Generally people will say it is not good to send push notifications from android because you have to keep your Firebase Legacy server key inside your android app . but i have a work around , just save you Firebase Legacy server key inside your firebase database and get it in splash screen every time when user opens app ,do not save this in sharepreferences , just pass it over intent data to all activities ( this way you wont be saving your Firebase Legacy server key inside your android app ) . This is still not very secure .