Friday 31 March 2017

Android Push Notification Using Firebase





Creating a new Android Project
  • Create a new Android Studio Project with an empty Activity
  • Once your project is loaded click on firebase from toolsmenu

  • After clicking on Firebase an assistant will open showing all the available firebase features.

  • Click on Cloud Messaging

  • You will see a link “Set Up Firebase Cloud Messaging”



  • Now you will see all option required “Set up Firebase Cloud Messaging”


  • Click on “Connect to Firebase” button. It will start a dialog. Insert project name and country select.
  • Now click on Connect to Firebase. And wait for a few seconds.

  • Again click on the button Add FCM to your app and you will see a dialog

  • Click on Accept Changes. And firebase is setup in your project now.


Generating Device Token

          MyFirebaseInstanceIDService.java



package com.pushnotification;

/**
 * Created by JAINISH on 2/12/2017.
 */

import android.util.Log;

import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;

//Class extending FirebaseInstanceIdService
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);

       
//calling the method store token and passing token
       
storeToken(refreshedToken);
    }

   
private void storeToken(String token) {
       
//we will save the token in sharedpreferences later
       
SharedPrefManager.getInstance(getApplicationContext()).saveDeviceToken(token);
    }
}

AndroidManifest.xml

Service we need to define this class in side AndroidManifest.xml. inside AndroidManifest.xml and write code inside application tag.

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

             SharedPrefManager.java


package com.pushnotification;

/**

 * Created by JAINISH on 2/12/2017.

 */

import android.content.Context;

import android.content.SharedPreferences;


public class SharedPrefManager {

    private static final String SHARED_PREF_NAME = "FCMSharedPref";

    private static final String TAG_TOKEN = "tagtoken";

    private static SharedPrefManager mInstance;

    private static Context mCtx;



    private SharedPrefManager(Context context) {

        mCtx = context;

    }

    public static synchronized SharedPrefManager getInstance(Context context) {

        if (mInstance == null) {

            mInstance = new SharedPrefManager(context);

        }

        return mInstance;

    }

    //this method will save the device token to shared preferences

    public boolean saveDeviceToken(String token){

        SharedPreferences sharedPreferences = mCtx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);

        SharedPreferences.Editor editor = sharedPreferences.edit();

        editor.putString(TAG_TOKEN, token);

        editor.apply();

        return true;

    }

    //this method will fetch the device token from shared preferences

    public String getDeviceToken(){

        SharedPreferences sharedPreferences = mCtx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE);

        return  sharedPreferences.getString(TAG_TOKEN, null);

    }

}

Activity_main.xml

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:id="@+id/activity_main"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:paddingBottom="@dimen/activity_vertical_margin"

    android:paddingLeft="@dimen/activity_horizontal_margin"

    android:paddingRight="@dimen/activity_horizontal_margin"

    android:paddingTop="@dimen/activity_vertical_margin"

    tools:context=".MainActivity">


    <Button

        android:layout_centerVertical="true"

        android:text="Display Token"

        android:id="@+id/buttonDisplayToken"

        android:layout_width="match_parent"

        android:layout_height="wrap_content" />


    <TextView

        android:id="@+id/textViewToken"

        android:layout_alignParentBottom="true"

        android:layout_width="match_parent"

        android:layout_height="wrap_content" />



</RelativeLayout>


·         MainActivity.java

package com.pushnotification;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

import android.widget.TextView;


public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    //defining views

    private Button buttonDisplayToken;

    private TextView textViewToken;

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        //getting views from xml

        textViewToken = (TextView) findViewById(R.id.textViewToken);

        buttonDisplayToken = (Button) findViewById(R.id.buttonDisplayToken);

        //adding listener to view

        buttonDisplayToken.setOnClickListener(this);

    }

    @Override

    public void onClick(View view) {

        if (view == buttonDisplayToken) {

            //getting token from shared preferences

            String token = SharedPrefManager.getInstance(this).getDeviceToken();

            //if token is not null

            if (token != null) {

                //displaying the token

                textViewToken.setText(token);

            } else {

                //if token is null that means something wrong

                textViewToken.setText("Token not generated");

            }

        }

    }

}

Creating Push Notification

·                   MyFirebaseMessagingService.java

package com.pushnotification;

/**
 * Created by JAINISH on 2/12/2017.
 */

import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class MyFirebaseMessagingService extends FirebaseMessagingService {
   
private static final String TAG = "MyFirebaseMsgService";
   
@Override
   
public void onMessageReceived(RemoteMessage remoteMessage) {

    }
}

·         AndroidManifest.xml

Service we need to define this class in side AndroidManifest.xml. inside AndroidManifest.xml and write code inside application tag.

<service

    android:name=".MyFirebaseMessagingService">

    <intent-filter>

        <action android:name="com.google.firebase.MESSAGING_EVENT"/>

    </intent-filter>

</service>

·         MyNotificationManager.java
package com.pushnotification;

/**

 * Created by JAINISH on 2/12/2017.

 */

import android.content.Intent;

import android.util.Log;

import com.google.firebase.messaging.FirebaseMessagingService;

import com.google.firebase.messaging.RemoteMessage;

import org.json.JSONException;

import org.json.JSONObject;


public class MyFirebaseMessagingService extends FirebaseMessagingService {


    private static final String TAG = "MyFirebaseMsgService";

    @Override

    public void onMessageReceived(RemoteMessage remoteMessage) {

        if (remoteMessage.getData().size() > 0) {

            Log.e(TAG, "Data Payload: " + remoteMessage.getData().toString());

            try {

                JSONObject json = new JSONObject(remoteMessage.getData().toString());

                sendPushNotification(json);

            } catch (Exception e) {

                Log.e(TAG, "Exception: " + e.getMessage());

            }

        }

    }

    //this method will display the notification

    //We are passing the JSONObject that is received from

    //firebase cloud messaging

    private void sendPushNotification(JSONObject json) {

        //optionally we can display the json into log

        Log.e(TAG, "Notification JSON " + json.toString());

        try {

            //getting the json data

            JSONObject data = json.getJSONObject("data");

            //parsing json data

            String title = data.getString("title");

            String message = data.getString("message");

            String imageUrl = data.getString("image");

            //creating MyNotificationManager object

            MyNotificationManager mNotificationManager = new MyNotificationManager(getApplicationContext());

            //creating an intent for the notification

            Intent intent = new Intent(getApplicationContext(), MainActivity.class);

            //if there is no image

            if(imageUrl.equals("null")){

                //displaying small notification

                mNotificationManager.showSmallNotification(title, message, intent);

            }else{

                //if there is an image

                //displaying a big notification

                mNotificationManager.showBigNotification(title, message, imageUrl, intent);

            }

        } catch (JSONException e) {

            Log.e(TAG, "Json Exception: " + e.getMessage());

        } catch (Exception e) {

            Log.e(TAG, "Exception: " + e.getMessage());

        }

    }

}

Creating Database



·         add library build.gradle

compile 'com.android.volley:volley:1.0.0'

·         activity_main.xml

we will modify the activity_main.xml

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:id="@+id/activity_main"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:paddingBottom="@dimen/activity_vertical_margin"

    android:paddingLeft="@dimen/activity_horizontal_margin"

    android:paddingRight="@dimen/activity_horizontal_margin"

    android:paddingTop="@dimen/activity_vertical_margin"

    tools:context=".MainActivity">



    <EditText

        android:layout_above="@+id/buttonRegister"

        android:hint="Enter email"

        android:id="@+id/editTextEmail"

        android:layout_width="match_parent"

        android:layout_height="wrap_content" />



    <Button

        android:layout_centerVertical="true"

        android:text="Register Device"

        android:id="@+id/buttonRegister"

        android:layout_width="match_parent"

        android:layout_height="wrap_content" />



</RelativeLayout>

·         MainActivity.java

package com.pushnotification;


import android.app.ProgressDialog;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.ProgressBar;

import android.widget.TextView;

import android.widget.Toast;

import com.android.volley.AuthFailureError;

import com.android.volley.Request;

import com.android.volley.RequestQueue;

import com.android.volley.Response;

import com.android.volley.VolleyError;

import com.android.volley.toolbox.StringRequest;

import com.android.volley.toolbox.Volley;

import org.json.JSONException;

import org.json.JSONObject;

import java.util.HashMap;

import java.util.Map;



public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    //defining views

    private Button buttonRegister;

    private EditText editTextEmail;

    private ProgressDialog progressDialog;

    //URL to RegisterDevice.php

    private static final String URL_REGISTER_DEVICE = "http://jrinfoway.com/Android_Eaxmple/push_notification/RegisterDevice.php";

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);



        //getting views from xml

        editTextEmail = (EditText) findViewById(R.id.editTextEmail);

        buttonRegister = (Button) findViewById(R.id.buttonRegister);



        //adding listener to view

        buttonRegister.setOnClickListener(this);

    }



    //storing token to mysql server

    private void sendTokenToServer() {

        progressDialog = new ProgressDialog(this);

        progressDialog.setMessage("Registering Device...");

        progressDialog.show();



        final String token = SharedPrefManager.getInstance(this).getDeviceToken();

        final String email = editTextEmail.getText().toString();



        if (token == null) {

            progressDialog.dismiss();

            Toast.makeText(this, "Token not generated", Toast.LENGTH_LONG).show();

            return;

        }



        StringRequest stringRequest = new StringRequest(Request.Method.POST, URL_REGISTER_DEVICE,

                new Response.Listener<String>() {

                    @Override

                    public void onResponse(String response) {

                        progressDialog.dismiss();

                        try {

                            JSONObject obj = new JSONObject(response);

                            Toast.makeText(MainActivity.this, obj.getString("message"), Toast.LENGTH_LONG).show();

                        } catch (JSONException e) {

                            e.printStackTrace();

                        }

                    }

                },

                new Response.ErrorListener() {

                    @Override

                    public void onErrorResponse(VolleyError error) {

                        progressDialog.dismiss();

                        Toast.makeText(MainActivity.this, error.getMessage(), Toast.LENGTH_LONG).show();

                    }

                }) {



            @Override

            protected Map<String, String> getParams() throws AuthFailureError {

                Map<String, String> params = new HashMap<>();

                params.put("email", email);

                params.put("token", token);

                return params;

            }

        };

        RequestQueue requestQueue = Volley.newRequestQueue(this);

        requestQueue.add(stringRequest);

    }



    @Override

    public void onClick(View view) {

        if (view == buttonRegister) {

            sendTokenToServer();

        }

    }

}

·         Getting Firebase Server Key

Go to Firebase Console and inside your project settings go to cloud messaging.
Find the Cloud Messaging  Server Key here, Copy it.
Now go inside Config.php file and put your Server Key.




·         EndPoints.java

package com.pushnotification;

/**
 * Created by JAINISH on 2/14/2017.
 */

public class EndPoints {
   
public static final String URL_REGISTER_DEVICE = "http://jrinfoway.com/Android_Eaxmple/push_notification/RegisterDevice.php";
   
public static final String URL_SEND_SINGLE_PUSH = "http://jrinfoway.com/Android_Eaxmple/push_notification/sendSinglePush.php";
   
public static final String URL_SEND_MULTIPLE_PUSH = "http://jrinfoway.com/Android_Eaxmple/push_notification/sendMultiplePush.php";
   
public static final String URL_FETCH_DEVICES = "http://jrinfoway.com/Android_Eaxmple/push_notification/GetRegisteredDevices.php";
}

·         activity_main.xml

we will modify the activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   
xmlns:tools="http://schemas.android.com/tools"
   
android:id="@+id/activity_main"
   
android:layout_width="match_parent"
   
android:layout_height="match_parent"
   
android:paddingBottom="@dimen/activity_vertical_margin"
   
android:paddingLeft="@dimen/activity_horizontal_margin"
   
android:paddingRight="@dimen/activity_horizontal_margin"
   
android:paddingTop="@dimen/activity_vertical_margin"
   
tools:context=".MainActivity">

    <
EditText
       
android:layout_above="@+id/buttonRegister"
       
android:hint="Enter email"
       
android:id="@+id/editTextEmail"
       
android:layout_width="match_parent"
       
android:layout_height="wrap_content" />

    <
Button
       
android:layout_centerVertical="true"
       
android:text="Register Device"
       
android:id="@+id/buttonRegister"
       
android:layout_width="match_parent"
       
android:layout_height="wrap_content" />

   
<!-- this button is added -->
   
<Button
       
android:text="Send Notification"
       
android:layout_width="match_parent"
       
android:layout_height="wrap_content"
       
android:layout_below="@+id/buttonRegister"
       
android:layout_centerHorizontal="true"
       
android:id="@+id/buttonSendNotification" />

</
RelativeLayout>

·         MainActivity.java

package com.pushnotification;


import android.app.ProgressDialog;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Map;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

   
//defining views
   
private Button buttonSendPush;
   
private Button buttonRegister;
   
private EditText editTextEmail;
   
private ProgressDialog progressDialog;

   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
        setContentView(R.layout.
activity_main);

       
//getting views from xml
       
editTextEmail = (EditText) findViewById(R.id.editTextEmail);
       
buttonRegister = (Button) findViewById(R.id.buttonRegister);
       
buttonSendPush = (Button) findViewById(R.id.buttonSendNotification);

       
//adding listener to view
       
buttonRegister.setOnClickListener(this);
       
buttonSendPush.setOnClickListener(this);
    }

   
//storing token to mysql server
   
private void sendTokenToServer() {
       
progressDialog = new ProgressDialog(this);
       
progressDialog.setMessage("Registering Device...");
       
progressDialog.show();

       
final String token = SharedPrefManager.getInstance(this).getDeviceToken();
       
final String email = editTextEmail.getText().toString();

       
if (token == null) {
           
progressDialog.dismiss();
            Toast.makeText(
this, "Token not generated", Toast.LENGTH_LONG).show();
           
return;
        }

        StringRequest stringRequest =
new StringRequest(Request.Method.POST, EndPoints.URL_REGISTER_DEVICE,
               
new Response.Listener<String>() {
                   
@Override
                   
public void onResponse(String response) {
                       
progressDialog.dismiss();
                       
try {
                            JSONObject obj =
new JSONObject(response);
                            Toast.makeText(MainActivity.
this, obj.getString("message"), Toast.LENGTH_LONG).show();
                        }
catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                },
               
new Response.ErrorListener() {
                   
@Override
                   
public void onErrorResponse(VolleyError error) {
                       
progressDialog.dismiss();
                        Toast.makeText(MainActivity.
this, error.getMessage(), Toast.LENGTH_LONG).show();
                    }
                }) {

           
@Override
           
protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> params =
new HashMap<>();
                params.put(
"email", email);
                params.put(
"token", token);
               
return params;
            }
        };
        RequestQueue requestQueue = Volley.newRequestQueue(
this);
        requestQueue.add(stringRequest);
    }

   
@Override
   
public void onClick(View view) {
       
if (view == buttonRegister) {
            sendTokenToServer();
        }

       
//starting send notification activity
       
if(view == buttonSendPush){
            startActivity(
new Intent(this, ActivitySendPushNotification.class));
        }
    }
}

·         activity_send_push_notification.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   
xmlns:tools="http://schemas.android.com/tools"
   
android:id="@+id/activity_send_push_notification"
   
android:layout_width="match_parent"
   
android:layout_height="match_parent"
   
android:orientation="vertical"
   
android:paddingBottom="@dimen/activity_vertical_margin"
   
android:paddingLeft="@dimen/activity_horizontal_margin"
   
android:paddingRight="@dimen/activity_horizontal_margin"
   
android:paddingTop="@dimen/activity_vertical_margin"
   
tools:context=".ActivitySendPushNotification">

    <
RadioGroup
       
android:id="@+id/radioGroup"
       
android:layout_width="match_parent"
       
android:layout_height="wrap_content"
       
android:orientation="horizontal">

        <
RadioButton
           
android:id="@+id/radioButtonSendAll"
           
android:layout_width="wrap_content"
           
android:layout_height="wrap_content"
           
android:text="Send to All" />

        <
RadioButton
           
android:id="@+id/radioButtonSendOne"
           
android:layout_width="wrap_content"
           
android:layout_height="wrap_content"
           
android:text="Send to One" />

    </
RadioGroup>

    <
Spinner
       
android:id="@+id/spinnerDevices"
       
android:layout_width="match_parent"
       
android:layout_height="wrap_content"></Spinner>

    <
EditText
       
android:id="@+id/editTextTitle"
       
android:layout_width="match_parent"
       
android:layout_height="wrap_content"
       
android:hint="Enter Message Title" />

    <
EditText
       
android:id="@+id/editTextMessage"
       
android:layout_width="match_parent"
       
android:layout_height="wrap_content"
       
android:hint="Enter Message" />

    <
EditText
       
android:id="@+id/editTextImageUrl"
       
android:layout_width="match_parent"
       
android:layout_height="wrap_content"
       
android:hint="Enter Image URL (Optional) " />

    <
Button
       
android:id="@+id/buttonSendPush"
       
android:layout_width="match_parent"
       
android:layout_height="wrap_content"
       
android:text="Send Push" />

</
LinearLayout>

·         MyVolley.java

package com.pushnotification;

/**
 * Created by JAINISH on 2/15/2017.
 */

import android.content.Context;
import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;

public class MyVolley {

   
private static MyVolley mInstance;
   
private RequestQueue mRequestQueue;
   
private static Context mCtx;

   
private MyVolley(Context context) {
       
mCtx = context;
       
mRequestQueue = getRequestQueue();
    }

   
public static synchronized MyVolley getInstance(Context context) {
       
if (mInstance == null) {
           
mInstance = new MyVolley(context);
        }
       
return mInstance;
    }

   
public RequestQueue getRequestQueue() {
       
if (mRequestQueue == null) {
           
// getApplicationContext() is key, it keeps you from leaking the
            // Activity or BroadcastReceiver if someone passes one in.
           
mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
        }
       
return mRequestQueue;
    }

   
public <T> void addToRequestQueue(Request<T> req) {
        getRequestQueue().add(req);
    }

}

·         ActivitySendPushNotification.java

package com.pushnotification;



import android.app.ProgressDialog;

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import android.text.TextUtils;

import android.view.View;

import android.widget.ArrayAdapter;

import android.widget.Button;

import android.widget.EditText;

import android.widget.RadioGroup;

import android.widget.Spinner;

import android.widget.Toast;



import com.android.volley.AuthFailureError;

import com.android.volley.Request;

import com.android.volley.Response;

import com.android.volley.VolleyError;

import com.android.volley.toolbox.StringRequest;



import org.json.JSONArray;

import org.json.JSONException;

import org.json.JSONObject;



import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;



public class ActivitySendPushNotification extends AppCompatActivity implements RadioGroup.OnCheckedChangeListener, View.OnClickListener {



    private Button buttonSendPush;

    private RadioGroup radioGroup;

    private Spinner spinner;

    private ProgressDialog progressDialog;



    private EditText editTextTitle, editTextMessage, editTextImage;



    private boolean isSendAllChecked;

    private List<String> devices;





    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_send_push_notification);



        radioGroup = (RadioGroup) findViewById(R.id.radioGroup);

        spinner = (Spinner) findViewById(R.id.spinnerDevices);

        buttonSendPush = (Button) findViewById(R.id.buttonSendPush);



        editTextTitle = (EditText) findViewById(R.id.editTextTitle);

        editTextMessage = (EditText) findViewById(R.id.editTextMessage);

        editTextImage = (EditText) findViewById(R.id.editTextImageUrl);



        devices = new ArrayList<>();



        radioGroup.setOnCheckedChangeListener(this);

        buttonSendPush.setOnClickListener(this);



        loadRegisteredDevices();

    }



    //method to load all the devices from database

    private void loadRegisteredDevices() {

        progressDialog = new ProgressDialog(this);

        progressDialog.setMessage("Fetching Devices...");

        progressDialog.show();



        StringRequest stringRequest = new StringRequest(Request.Method.GET, EndPoints.URL_FETCH_DEVICES,

                new Response.Listener<String>() {

                    @Override

                    public void onResponse(String response) {

                        progressDialog.dismiss();

                        JSONObject obj = null;

                        try {

                            obj = new JSONObject(response);

                            if (!obj.getBoolean("error")) {

                                JSONArray jsonDevices = obj.getJSONArray("devices");



                                for (int i = 0; i < jsonDevices.length(); i++) {

                                    JSONObject d = jsonDevices.getJSONObject(i);

                                    devices.add(d.getString("email"));

                                }



                                ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(

                                        ActivitySendPushNotification.this,

                                        android.R.layout.simple_spinner_dropdown_item,

                                        devices);



                                spinner.setAdapter(arrayAdapter);

                            }

                        } catch (JSONException e) {

                            e.printStackTrace();

                        }

                    }

                },

                new Response.ErrorListener() {

                    @Override

                    public void onErrorResponse(VolleyError error) {



                    }

                }) {



        };

        MyVolley.getInstance(this).addToRequestQueue(stringRequest);



    }



    //this method will send the push

    //from here we will call sendMultiple() or sendSingle() push method

    //depending on the selection

    private void sendPush() {

        if(isSendAllChecked){

            sendMultiplePush();

        }else{

            sendSinglePush();

        }

    }



    private void sendMultiplePush(){

        final String title = editTextTitle.getText().toString();

        final String message = editTextMessage.getText().toString();

        final String image = editTextImage.getText().toString();

        final String email = spinner.getSelectedItem().toString();



        progressDialog.setMessage("Sending Push");

        progressDialog.show();



        StringRequest stringRequest = new StringRequest(Request.Method.POST, EndPoints.URL_SEND_SINGLE_PUSH,

                new Response.Listener<String>() {

                    @Override

                    public void onResponse(String response) {

                        progressDialog.dismiss();



                        Toast.makeText(ActivitySendPushNotification.this, response, Toast.LENGTH_LONG).show();

                    }

                },

                new Response.ErrorListener() {

                    @Override

                    public void onErrorResponse(VolleyError error) {



                    }

                }) {

            @Override

            protected Map<String, String> getParams() throws AuthFailureError {

                Map<String, String> params = new HashMap<>();

                params.put("title", title);

                params.put("message", message);



                if (!TextUtils.isEmpty(image))

                    params.put("image", image);

                params.put("email", email);

                return params;

            }

        };

        MyVolley.getInstance(this).addToRequestQueue(stringRequest);

    }

    private void sendSinglePush(){

        final String title = editTextTitle.getText().toString();

        final String message = editTextMessage.getText().toString();

        final String image = editTextImage.getText().toString();

        progressDialog.setMessage("Sending Push");

        progressDialog.show();

        StringRequest stringRequest = new StringRequest(Request.Method.POST, EndPoints.URL_SEND_MULTIPLE_PUSH,

                new Response.Listener<String>() {

                    @Override

                    public void onResponse(String response) {

                        progressDialog.dismiss();



                        Toast.makeText(ActivitySendPushNotification.this, response, Toast.LENGTH_LONG).show();

                    }

                },

                new Response.ErrorListener() {

                    @Override

                    public void onErrorResponse(VolleyError error) {

                    }

                }) {

            @Override

            protected Map<String, String> getParams() throws AuthFailureError {

                Map<String, String> params = new HashMap<>();

                params.put("title", title);

                params.put("message", message);



                if (!TextUtils.isEmpty(image))

                    params.put("image", image);

                return params;

            }

        };



        MyVolley.getInstance(this).addToRequestQueue(stringRequest);

    }

    @Override

    public void onCheckedChanged(RadioGroup radioGroup, int i) {

        switch (radioGroup.getCheckedRadioButtonId()) {

            case R.id.radioButtonSendAll:

                isSendAllChecked = true;

                spinner.setEnabled(false);

                break;

            case R.id.radioButtonSendOne:

                isSendAllChecked = false;

                spinner.setEnabled(true);

                break;

        }

    }



    @Override

    public void onClick(View view) {

        //calling the method send push on button click

        sendPush();

    }

}

PHP Files

·         Config.php

<?php
 define('DB_USERNAME','your user name');
 define('DB_PASSWORD','your password');
 define('DB_NAME','your database name');
 define('DB_HOST','localhost');
//defined a new constant for firebase api key
 define('FIREBASE_API_KEY', ‘YOUR_SERVER_KEY');


·         DbConnect.php
<?php
//Class DbConnect
class DbConnect
{
    //Variable to store database link
    private $con;
    //Class constructor
    function __construct()
    {
    }
    //This method will connect to the database
    function connect()
    {
        //Including the config.php file to get the database constants
        include_once dirname(__FILE__) . '/Config.php';
        //connecting to mysql database
        $this->con = new mysqli(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME);
        //Checking if any error occured while connecting
        if (mysqli_connect_errno()) {
            echo "Failed to connect to MySQL: " . mysqli_connect_error();
        }
        //finally returning the connection link
        return $this->con;
    }
}

·         DbOperation.php
<?php
class DbOperation
{
    //Database connection link
    private $con;
    //Class constructor
    function __construct()
    {
        //Getting the DbConnect.php file
        require_once dirname(__FILE__) . '/DbConnect.php';
        //Creating a DbConnect object to connect to the database
        $db = new DbConnect();
        //Initializing our connection link of this class
        //by calling the method connect of DbConnect class
        $this->con = $db->connect();
    }
    //storing token in database
    public function registerDevice($email,$token){
        if(!$this->isEmailExist($email)){
            $stmt = $this->con->prepare("INSERT INTO devices (email, token) VALUES (?,?) ");
            $stmt->bind_param("ss",$email,$token);
            if($stmt->execute())
                return 0; //return 0 means success
            return 1; //return 1 means failure
        }else{
            return 2; //returning 2 means email already exist
        }
    }
    //the method will check if email already exist
    private function isEmailexist($email){
        $stmt = $this->con->prepare("SELECT id FROM devices WHERE email = ?");
        $stmt->bind_param("s",$email);
        $stmt->execute();
        $stmt->store_result();
        $num_rows = $stmt->num_rows;
        $stmt->close();
        return $num_rows > 0;
    }
    //getting all tokens to send push to all devices
    public function getAllTokens(){
        $stmt = $this->con->prepare("SELECT token FROM devices");
        $stmt->execute();
        $result = $stmt->get_result();
        $tokens = array();
        while($token = $result->fetch_assoc()){
            array_push($tokens, $token['token']);
        }
        return $tokens;
    }
    //getting a specified token to send push to selected device
    public function getTokenByEmail($email){
        $stmt = $this->con->prepare("SELECT token FROM devices WHERE email = ?");
        $stmt->bind_param("s",$email);
        $stmt->execute();
        $result = $stmt->get_result()->fetch_assoc();
        return array($result['token']);       
    }
    //getting all the registered devices from database
    public function getAllDevices(){
        $stmt = $this->con->prepare("SELECT * FROM devices");
        $stmt->execute();
        $result = $stmt->get_result();
        return $result;
    }
}
?>
·         Firebase.php
<?php
class Firebase {
    public function send($registration_ids, $message) {
        $fields = array(
            'registration_ids' => $registration_ids,
            'data' => $message,
        );
        return $this->sendPushNotification($fields);
    }  
    /*
    * This function will make the actuall curl request to firebase server
    * and then the message is sent
    */
    private function sendPushNotification($fields) {    
        //importing the constant files
        require_once 'Config.php';      
        //firebase server url to send the curl request
        $url = 'https://fcm.googleapis.com/fcm/send';
        //building headers for the request
        $headers = array(
            'Authorization: key=' . FIREBASE_API_KEY,
            'Content-Type: application/json'
        );
        //Initializing curl to open a connection
        $ch = curl_init();
        //Setting the curl url
        curl_setopt($ch, CURLOPT_URL, $url);
        //setting the method as post
        curl_setopt($ch, CURLOPT_POST, true);
        //adding headers
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        //disabling ssl support
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);       
        //adding the fields in json format
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
        //finally executing the curl request
        $result = curl_exec($ch);
        if ($result === FALSE) {
            die('Curl failed: ' . curl_error($ch));
        }
        //Now close the connection
        curl_close($ch);
        //and return the result
        return $result;
    }
}
?>
·         GetRegisteredDevices.php
<?php  
 require_once 'DbOperation.php';
 $db = new DbOperation();  
 $devices = $db->getAllDevices();
 $response = array();  
 $response['error'] = false;
 $response['devices'] = array();

 while($device = $devices->fetch_assoc()){
 $temp = array();
 $temp['id']=$device['id'];
 $temp['email']=$device['email'];
 $temp['token']=$device['token'];
 array_push($response['devices'],$temp);
 }
 echo json_encode($response);
?>

·         Push.php
<?php
class Push {
    //notification title
    private $title;
    //notification message
    private $message;
    //notification image url
    private $image;
    //initializing values in this constructor
    function __construct($title, $message, $image) {
         $this->title = $title;
         $this->message = $message;
         $this->image = $image;
    }   
    //getting the push notification
    public function getPush() {
        $res = array();
        $res['data']['title'] = $this->title;
        $res['data']['message'] = $this->message;
        $res['data']['image'] = $this->image;
        return $res;
    }
}
?>


·         RegisterDevice.php
<?php
 require_once 'DbOperation.php';
 $response = array();  
 if($_SERVER['REQUEST_METHOD']=='POST'){
 $token = $_POST['token'];
 $email = $_POST['email'];
 $db = new DbOperation();  
 $result = $db->registerDevice($email,$token);
 if($result == 0){
 $response['error'] = false;
 $response['message'] = 'Device registered successfully';
 }elseif($result == 2){
 $response['error'] = true;
 $response['message'] = 'Device already registered';
 }else{
 $response['error'] = true;
 $response['message']='Device not registered';
 }
 }else{
 $response['error']=true;
 $response['message']='Invalid Request...';
 }
 echo json_encode($response);
?>


·         SendMultiplePush.php
<?php
//importing required files
require_once 'DbOperation.php';
require_once 'Firebase.php';
require_once 'Push.php';
$db = new DbOperation();
$response = array();
if($_SERVER['REQUEST_METHOD']=='POST'){          
            //hecking the required params
            if(isset($_POST['title']) and isset($_POST['message'])) {
                        //creating a new push
                        $push = null;
                        //first check if the push has an image with it
                        if(isset($_POST['image'])){
                                    $push = new Push(
                                                            $_POST['title'],
                                                            $_POST['message'],
                                                            $_POST['image']
                                                );
                        }else{
                                    //if the push don't have an image give null in place of image
                                    $push = new Push(
                                                            $_POST['title'],
                                                            $_POST['message'],
                                                            null
                                                );
                        }
                        //getting the push from push object
                        $mPushNotification = $push->getPush();
                        //getting the token from database object
                        $devicetoken = $db->getAllTokens();
                        //creating firebase class object
                        $firebase = new Firebase();
                        //sending push notification and displaying result
                        echo $firebase->send($devicetoken, $mPushNotification);
            }else{
                        $response['error']=true;
                        $response['message']='Parameters missing';
            }
}else{
            $response['error']=true;
            $response['message']='Invalid request';
}
echo json_encode($response);
·         SendSinglePush.php
<?php
//importing required files
require_once 'DbOperation.php';
require_once 'Firebase.php';
require_once 'Push.php';  
$db = new DbOperation();
$response = array();

if($_SERVER['REQUEST_METHOD']=='POST'){
 //hecking the required params
 if(isset($_POST['title']) and isset($_POST['message']) and isset($_POST['email'])){
 //creating a new push
 $push = null;
 //first check if the push has an image with it
 if(isset($_POST['image'])){
 $push = new Push(
 $_POST['title'],
 $_POST['message'],
 $_POST['image']
 );
 }else{
 //if the push don't have an image give null in place of image
 $push = new Push(
 $_POST['title'],
 $_POST['message'],
 null
 );
 }
 //getting the push from push object
 $mPushNotification = $push->getPush();

 //getting the token from database object
 $devicetoken = $db->getTokenByEmail($_POST['email']);

 //creating firebase class object
 $firebase = new Firebase();

 //sending push notification and displaying result
 echo $firebase->send($devicetoken, $mPushNotification);
 }else{
 $response['error']=true;
 $response['message']='Parameters missing';
 }
}else{
 $response['error']=true;
 $response['message']='Invalid request';
}

echo json_encode($response);