Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Building a Firebase Cloud Messaging App (Part One)

DZone's Guide to

Building a Firebase Cloud Messaging App (Part One)

Firebase Cloud Messaging can be an easy way to incorporate messaging into your app. This guide walks you through making an Android app with FCM.

· Cloud Zone
Free Resource

MongoDB Atlas is a database as a service that makes it easy to deploy, manage, and scale MongoDB. So you can focus on innovation, not operations. Brought to you in partnership with MongoDB.

One of the demo apps I’ve been showing as I do talks around the world is a basic Firebase Cloud Messaging one — where I build an Android app that registers itself with a very simple app server (running at http://www.laurencemoroney.com/fcm/homepage.php).

When you go to this page you can then send a notification to all registered devices, or just pick one. I’ve had lots of requests for source code and advice in how to build one of these, so I figured I’ll blog it here.

Image title

The ArchitectureThere’s a lot of concepts at play here — using FCM, building an app server, building a client app and registering it etc. So let’s take a look at how this would work step by step. It’s also really worth reading this page: https://firebase.google.com/docs/cloud-messaging/server — in particular for getting the authorization key that you’ll need later.

First of all, your app needs to talk to FCM to get an Instance token. This token is used to identify the device and not the person using the device. Once it has gotten this from FCM, then FCM can, in future direct messages to this device using this identifier.

Step 1: Getting an Instance Token From FCM

For building apps like this, you should consider FCM to be a simple ‘black box’ API that you give commands to and it responds on your behalf. If you want to know what the instance IDs are for your users you need to store them yourself, and the simplest way to do this is with your own app server. So, step 2 would be to pass these details to your app server so it can store them for you!

Image title

Step 2: Sending Instance Tokens to Your App Server

Once your app server has the instance tokens, it can then talk to FCM on your behalf — commanding it to send messages to devices, groups, topics etc. This is shown in step 3.

Image title

Step 3: App Server Tells FCM to Send Messages to Devices

That’s pretty much it for the architecture for a simple app/server that uses FCM. In the next section, we’ll look at how to build a simple app server — using the code from the one at http://laurencemoroney.com/fcm/homepage.php.

Building the App ServerImportant: This source code is for demonstration and learning purposes only. Under no circumstances should you use it in a production environment!

The simple app server used here has three main functions:

  1. Accept posts from the app with instance tokens and store them in a database.
  2. Create a page with a list of all tokens, and forms that allow you to send a message to one or all registered devices.
  3. Tell FCM to send the desired message to the desired device(s).

Accept posts from the app with instance tokens and store them in a databaseCreate a page with a list of all tokens, and forms that allow you to send a message to one or all registered devicesTell FCM to send the desired message to the desired device(s)Let’s take a look at each of these in turn.

Storing the Instance Tokens

In this example, I just created a simple MySQL database to store the token and the time it was registered with the app server. The SQL to create a table to store these is here:

CREATE TABLE IF NOT EXISTS `fcm_users` (
    `id` int(11) NOT NULL,
    `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
    `fcm_regID` text NOT NULL
)


And then in your PHP you need to accept a POST from the client, carrying the token:

if (isset($_POST["regid"])) {
  $fcm_regid = $_POST["regid"]; 
  include_once 'db_functions.php';
  $db = new DB_Functions();
  $res = $db->storeUser($fcm_regid);
  echo "Done!";
  } else {
    echo "Problem with parameters";
  }
}


This uses the ‘storeUser’ function from the ‘db_functions.php’ file that I created for modularity. Here’s the code:

class DB_Functions {
  private $db;
  function __construct() {
    include_once 'db_connect.php';
    $this->db = new DB_Connect();
    $this->db->connect();
  }
  function __destruct() {
  }
  public function storeUser($fcm_regid) {
    $result = mysql_query("INSERT INTO fcm_users(fcm_regID, created_at) VALUES('$fcm_regid', NOW())");
    //.. Errror handling code here
  }
  public function getAllUsers() {
    $result = mysql_query("select * FROM fcm_users");
    return $result;
  }
}


Pretty straightforward stuff. Next up, we’ll take a look at the page the lists all the tokens, and allows you to send a message to one or all of the devices registered to these tokens.

Listing the Registered Devices

This is the heart of the UI of the app server’s website. It’s a simple page that creates a form for each of the tokens that is saved in the database. It then generates a form for each of these, and another form that can be used to ‘send to all’. The core of this is in the javascript code. It receives a parameter from the form which is either ‘all’ (when you choose to send to all), or the id corresponding to the token id for a particular form. It then calls lm_send.php, passing it the message text and either ‘all’ or a specific token.

Here’s the code:

<!DOCTYPE html>
<html>
    <head>
        <title>FCM Test Page</title>
	<link rel="stylesheet" type="text/css" href="fcmsite.css">
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
        <script type="text/javascript">
	function sendPushNotification(id){
		var rid;
		var msg;
		if(id=='all'){
		    rid = 'all';
		    msg = $('#allform textarea[name=message]').val();
		} else {
		    rid = $('#form' + id + ' input[name=regId]').val();
		    msg = $('#form' + id + ' textarea[name=message]').val();
		}
		$.ajax({
			url: "lm_send.php?message=" + msg + "&regid=" + rid
		});
		return false;
	}
        </script>
        
    </head>
    <body>
        <?php
        include_once 'db_functions.php';
        $db = new DB_Functions();
        $users = $db->getAllUsers();
        if ($users != false)
            $no_of_users = mysql_num_rows($users);
        else
            $no_of_users = 0;
        ?>
        <div class="container">
        	<h1>Send to all registered devices</h1>
            <form id="allform" name="" method="post" onsubmit="return sendPushNotification('all')">
                <div class="send_container">                                
                    <textarea rows="3" name="message" id="message" cols="25" class="txt_message" placeholder="Type message here"></textarea>
                    <input type="submit" class="send_btn" value="Send" onclick=""/>
                </div>
            </form>        	  
            <h1>No of Devices Registered: <?php echo $no_of_users; ?></h1>
            <hr/>
            <ul class="devices">
                <?php
                if ($no_of_users > 0) {
                    ?>
                    <?php
                    while ($row = mysql_fetch_array($users)) {
                        ?>
                        <li>
                            <form id="form<?php echo $row["id"] ?>" name="" method="post" onsubmit="return sendPushNotification('<?php echo $row["id"] ?>')">
                                <label>ID: </label> <span><?php echo $row["fcm_regID"] ?></span>
                                <div class="clear"></div>
                                <div class="send_container">                                
                                    <textarea rows="3" name="message" id="message" cols="25" class="txt_message" placeholder="Type message here"></textarea>
                                    <input type="hidden" name="regId" id="regId" value="<?php echo $row["fcm_regID"] ?>"/>
                                    <input type="submit" class="send_btn" value="Send" onclick=""/>
                                </div>
                            </form>
                        </li>
                    <?php }
                } else { ?> 
                    <li>
                        No Users Registered Yet!
                    </li>
                <?php } ?>
            </ul>
        </div>
    </body>
</html>


So, for example, when you run this page, you’ll see something like this:

Entering the message in the top form will pass ‘all’ to the Javascript function, where entering into one of the others will send the contents of the token (i.e. e_v8g…)

…and that’s it. So, let’s now take a look at lm_send.php which tells FCM to deliver the message for you…

Sending the Message

Sending the message is then simply a case of calling the FCM endpoint for sending a message and passing it your command in is desired format. This is documented here.

For a single device, it’s pretty straightforward — just send to the regid that was passed into this function. When it’s ‘all’ you just query your DB for each of them, and store them in an array.

As I used PHP, it was easy to then just use curl to send the message!

<?php
  if(isset($_GET["message"])){
    $message = $_GET["message"];
  } else {
    $message = "Test Message";
  }
  $data = array("m" => $message);
  if(isset($_GET["regid"])){
    $regid = $_GET["regid"];
  } else {
    $regid = "testid";
  }
  if($regid=='all'){
    include_once 'db_functions.php';
    $db = new DB_Functions();
    $sql = mysql_query("select fcm_regid FROM fcm_users");
    $regdata = array();
    while($row = mysql_fetch_array($sql)){
      $regdata[] = $row[0];
    }
  } else {
    $regdata = array($regid);	
  }
 
  $url = 'https://fcm.googleapis.com/fcm/send';
  $headers = array(
    'Authorization: key=YOUR_AUTHORIZATION_KEY',
    'Content-Type: application/json'
  );
	
  $fields = array(
    'registration_ids' => $regdata,
    'data' => $data
  );
	
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);	
  curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
  $result = curl_exec($ch);				
  if ($result === FALSE) {
    die('Curl failed: ' . curl_error($ch));
  }
  curl_close($ch);
?>


And that’s it for this part of the tutorial. In part 2, I’ll talk about the other side of this — the Android app, and what I did to get the instance token, register it with this server, and then respond to incoming messages.

As always, any questions, hit me up on Twitter: @lmoroney.

MongoDB Atlas is the best way to run MongoDB on AWS — highly secure by default, highly available, and fully elastic. Get started free. Brought to you in partnership with MongoDB.

Topics:
cloud ,tutorial ,firebase ,messaging apps ,android app

Published at DZone with permission of Laurence Moroney, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}