Pages

Android Push Notifications using Firebase Cloud Messaging (FCM), PHP and MySQL

In this tutorial we will learn how to send notification from our device to all registered device using FCM and app server.

In recent times, Google moved from Google Cloud Messaging (GCM) to Firebase Cloud Messaging (FCM). Just like GCM, FCM is a cross-platform messaging solution that allows you to send messages. FCM is completely free and there are no limitations.
If you have followed any of my previous tutorials about GCM, I strongly recommend you migrate to Firebase today itself. In this article we learn the features of firebase cloud messaging by building a simple app. We’ll also learn how to integrate firebase to your backend, so that you can send the messages from your server.
  • Create a new Android Studio project and click on next button.

  • Choose minimum SDK and click on next button.

  • Choose an empty activity and click on next button.

  • Name your activity and click next.


  • Go to Firebase Console and create a new project. Choose add firebase to your Android app. Get your packagename from your manifest file, enter app nickname, get SHA-1 from typing command for Linux
keytool -exportcert -list -v \
-alias androiddebugkey -keystore ~/.android/debug.keystore

Password is android.
Click on AddApp. Download googleservice.json file and put this file to your Android Studio project's app folder.

Add Firebase SDk. 
  • go to build.gradle and add the following dependencies-
          1. compile 'com.google.firebase:firebase-core:10.2.0'
          2. compile 'com.google.firebase:firebase-messaging:10.2.0
          3. compile 'com.google.firebase:firebase-crash:10.2.0'
          4. compile 'com.android.volley:volley:1.0.0'
          5. apply plugin: 'com.google.gms.google-services'
          6. classpath 'com.google.gms:google-services:3.0.0'
              //add in build.gradle(project) 
  • Create a new class MyFirebaseInstanceIdService. This class will call only when our app install or when we clear app data.  Add the following code - 

public class MyFirebaseMessagingService extends FirebaseMessagingService {

    private static final String TAG =  "FirebaseMessagingService";

    @Override    
    public void onMessageReceived(RemoteMessage remoteMessage) {
        Log.d(TAG, "From: "+remoteMessage.getFrom());

        // Check if message contains a data payload.        
        if (remoteMessage.getData().size() > 0) {
            Log.d(TAG, "Message data payload: " + remoteMessage.getData());
        }

        // Check if message contains a notification payload.        
        if (remoteMessage.getNotification() != null) {
            Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody());
        }

        sendNotification(remoteMessage.getData());
    }

    private void sendNotification(Map<String,String> messageBody) {
        Intent intent = new Intent(this, MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);

        final int not_nu=generateRandom();

        PendingIntent pendingIntent = PendingIntent.getActivity(this,not_nu/* Request code */, intent,
                PendingIntent.FLAG_ONE_SHOT);

        Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);

        NotificationCompat.BigTextStyle bigText = new NotificationCompat.BigTextStyle();
        bigText.bigText(messageBody.get("message"));
        bigText.setBigContentTitle(messageBody.get("title"));

        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_notifications_none_black_24dp)
                .setContentTitle(messageBody.get("title"))
                .setContentText(messageBody.get("message"))
                .setAutoCancel(true)
                .setStyle(bigText)
                .setSound(defaultSoundUri)
                .setContentIntent(pendingIntent);


        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        notificationManager.notify(not_nu/* ID of notification */, notificationBuilder.build());
    }

    public int generateRandom(){
        Random random = new Random();
        return random.nextInt(9999 - 1000) + 1000;
    }
}


  • I am using free domain at https://in.000webhost.com/ Login there and choose create website. Upload StoreToken.php. Create database and then create database table which contain one field of token.
  • For storing token to our app server create StoreToken.php
<?php $servername = "localhost"; $username = "Your database username"; $password = "Your database password"; try { $conn = new PDO("mysql:host=$servername;dbname=Your database id in phpMyAdmin", $username, $password); // set the PDO error mode to exception $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $token=$_GET["token"]; $sql="insert into TokenStore values(?)"; $result =$conn->prepare($sql); $result->execute([$token]); } catch(PDOException $e) { echo "Connection failed: " . $e->getMessage(); } ?>
  • Create a new class MyFirebaseMessagingService.
When new notification received then onMessageReceived will called. SendNotification method help us to show notification in device status bar.
public class MyFirebaseMessagingService extends FirebaseMessagingService { private static final String TAG = "FirebaseMessagingService"; @Override public void onMessageReceived(RemoteMessage remoteMessage) { Log.d(TAG, "From: "+remoteMessage.getFrom()); // Check if message contains a data payload. if (remoteMessage.getData().size() > 0) { Log.d(TAG, "Message data payload: " + remoteMessage.getData()); } // Check if message contains a notification payload. if (remoteMessage.getNotification() != null) { Log.d(TAG, "Message Notification Body: " + remoteMessage.getNotification().getBody()); } sendNotification(remoteMessage.getData()); } private void sendNotification(Map<String,String> messageBody) { Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); final int not_nu=generateRandom(); PendingIntent pendingIntent = PendingIntent.getActivity(this,not_nu/* Request code */, intent, PendingIntent.FLAG_ONE_SHOT); Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationCompat.BigTextStyle bigText = new NotificationCompat.BigTextStyle(); bigText.bigText(messageBody.get("message")); bigText.setBigContentTitle(messageBody.get("title")); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_notifications_none_black_24dp) .setContentTitle(messageBody.get("title")) .setContentText(messageBody.get("message")) .setAutoCancel(true) .setStyle(bigText) .setSound(defaultSoundUri) .setContentIntent(pendingIntent); NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(not_nu/* ID of notification */, notificationBuilder.build()); } public int generateRandom(){ Random random = new Random(); return random.nextInt(9999 - 1000) + 1000; } }
  • add the Internet permission in your manifest file
<uses-permission android:name="android.permission.INTERNET"/> and following services - <service android:name=".MyFirebaseMessagingService"> <intent-filter> <action android:name="com.google.firebase.MESSAGING_EVENT" /> </intent-filter> </service> <service android:name=".MyFirebaseInstanceIdService"> <intent-filter> <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/> </intent-filter> </service> <meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="@drawable/ic_notifications_none_black_24dp" /> <meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="@color/colorAccent" />
  • In activity_main.xml file add the following code -
<?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_main" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.chahat.notifications.MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="title" android:layout_marginTop="5dp"/> <EditText android:id="@+id/et_title" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Title" android:layout_marginTop="5dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Message" android:layout_marginTop="5dp"/> <EditText android:id="@+id/et_notification" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="Notification" android:layout_marginTop="5dp"/> <Button android:id="@+id/bt_sendNotification" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Send Notification" android:layout_marginTop="5dp"/> </LinearLayout>

  • In MainActivity add following code -
public class MainActivity extends AppCompatActivity { String SERVER_ADDRESS = "https://websitename.000webhostapp.com/notification.php?token="; EditText et_title,et_notification; Button bt_sendNotification; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); et_title = (EditText) findViewById(R.id.et_title); et_notification = (EditText) findViewById(R.id.et_notification); bt_sendNotification = (Button) findViewById(R.id.bt_sendNotification); final String token = FirebaseInstanceId.getInstance().getToken(); bt_sendNotification.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (et_title.getText().toString().trim().isEmpty()||et_notification.getText().toString().trim().isEmpty()) { Toast.makeText(getApplicationContext(),"Enter title and text",Toast.LENGTH_SHORT); }else { String title = et_title.getText().toString(); String notification = et_notification.getText().toString(); sendNotificationToappServer(token,title,notification); } } }); } public void sendNotificationToappServer(final String token,final String title, final String notification){ StringRequest stringRequest = new StringRequest(Request.Method.POST,SERVER_ADDRESS+token, new Response.Listener<String>() { @Override public void onResponse(String response) { /* Toast.makeText(MainActivity.this,response,Toast.LENGTH_LONG).show();*/ } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Toast.makeText(MainActivity.this,error.toString(),Toast.LENGTH_LONG).show(); } }){ @Override protected Map<String,String> getParams(){ Map<String,String> params = new HashMap<String, String>(); params.put("title",title); params.put("message",notification); return params; } }; RequestQueue requestQueue = Volley.newRequestQueue(this); requestQueue.add(stringRequest); } }

  • Now create notification.php file and upload it to app server.
<?php $servername = "localhost"; $username = "Your database username"; $password = "Your database password"; $conn = new PDO("mysql:host=$servername;dbname=Your database id at phpMyAdmin", $username, $password); // set the PDO error mode to exception $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); define( 'API_ACCESS_KEY', 'Firebase Cloud Messaging api key' ); $myToken = $_GET["token"]; //apply this query if you want that notification receive by every registered token other than you $sql = " SELECT * FROM TokenStore WHERE token!='$myToken' "; //apply this query if you want that notification receive by every registerd token including you if you are sending a notification $sql = " SELECT token FROM TokenStore"; $resultt = $conn->prepare($sql); $resultt->execute(); $token = array(); if ($resultt->rowCount()>0) { while($row =$resultt->fetch()) { $token[]=$row["token"]; echo $row["token"]; } } var_dump($token); $title = $_POST["title"]; $notification = $_POST["message"]; $msg = [ 'message' => $notification, 'title' => $title ]; $fields = [ 'registration_ids' => $token, 'data' => $msg ]; $headers = [ 'Authorization: key=' . API_ACCESS_KEY, 'Content-Type: application/json' ]; $ch = curl_init(); curl_setopt( $ch,CURLOPT_URL, 'https://fcm.googleapis.com/fcm/send' ); curl_setopt( $ch,CURLOPT_POST, true ); curl_setopt( $ch,CURLOPT_HTTPHEADER, $headers ); curl_setopt( $ch,CURLOPT_RETURNTRANSFER, true ); curl_setopt( $ch,CURLOPT_SSL_VERIFYPEER, false ); curl_setopt( $ch,CURLOPT_POSTFIELDS, json_encode( $fields ) ); $result = curl_exec($ch ); curl_close( $ch ); echo $result; ?>
  • For API_ACCESS_KEY
goto firebase console then in project click on overview option and choose project setting. Then in project setting click on CloudMessaging and server key is your API_ACCESS_KEY. Now Your work is completed. Run app in your device.