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

Building a Firebase Cloud Messaging App (Part 2)

DZone's Guide to

Building a Firebase Cloud Messaging App (Part 2)

Now that you've got your FCM app server set up, it's time to incorporate Firebase Cloud Messaging into a simple Android app.

· Cloud Zone ·
Free Resource

Site24x7 - Full stack It Infrastructure Monitoring from the cloud. Sign up for free trial.

In part one of this series, I showed how to build a (very) simple app server to be used with Firebase Cloud Messaging. This server gathered instance tokens for devices that used the app, and from there it was able to send messages to one or all of the devices that use the app.

In this article, I’m going to go to the other side of the equation — and that is to show how to build the app itself!

Create an Android App and Add it to Your Firebase Console

First off, create a simple Android App. I’m using Android Studio, and I simply created a new app with the ‘Empty Activity’ template. This gives me the foundation I need to build my own app on. Importantly, you need to remember the package name that you created the app with. In my case I built an app called  com.google.devrel.lmoroney.myapplication.

Now, in Android Studio, go to the Tools menu and select ‘Firebase’. You’ll see the assistant pane on the right with a list of Firebase technologies. Select ‘Cloud Messaging’, and you’ll see a link to ‘Set up Firebase Cloud Messaging.’

Image title

Click the link and you’ll be taken to another pane with three steps.

The first of these is to ‘Connect to Firebase’, and selecting it will give you a dialog asking if you want to Create a New Firebase project or choose an existing one. Create a new one. Here you can see where I created a new one called ‘LaurenceBlogFCMDemo.’

Image title

Click ‘Connect to Firebase’ and you’ll be off to the races. Note the status in the upper right-hand corner of Android Studio:

Image title

Once it’s done, you should see the ‘project created’ message. Now you can go to step two, which is to add FCM to your app.

Click the button in the assistant:

Image title

You’ll see the ‘Add Cloud Messaging’ dialog which tells you what it’s going to do — namely updating your build.gradle files with what FCM needs.

Image title

Click ‘Accept Changes’ in this dialog, and Android Studio will do the rest. It may take a few moments for the Gradle Sync to finish.

If you hit a bug, where the Gradle sync fails because of a missing API key/current key — learn how to fix it here.

You’re now ready to start coding your app!

Building Your App

For the first step, add a button to your activity_main layout file. Label it ‘Register’, and give it a name…I called mine btnRegister. When I was done, my layout looked like this:

<?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: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="com.laurencemoroney.fcmtest.MainActivity">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="register"
        android:id="@+id/btnRegister"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="42dp" />

</RelativeLayout>


Now, in MainActivity.java, in your onCreate function, you can add an onclick listener for this button. This can call the Firebase instance id service to get your token, which is then used to register with your app server. In this case, I load the token into a Hashmap with the key ‘regid’. I then use a service called ‘CallFCM’ to do the communication with my app server. You’ll see that in the next step.

Here’s the code for MainActivity.java:

package com.google.devrel.lmoroney.myapplication;
 
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
 
import com.google.firebase.iid.FirebaseInstanceId;
 
import java.util.HashMap;
 
public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button btnRegister = (Button) findViewById(R.id.btnRegister);
        btnRegister.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                HashMap<String, String> params = new HashMap();
                params.put("regid", FirebaseInstanceId.getInstance().getToken());
                new CallFCM().execute(params);
            }
        });
    }
}


Let’s now take a look at what it takes to asynchronously call the app server in CallFCM()

Calling Your App Server With the Instance Token

Posting the instance token to your app server is an asynchronous operation that shouldn’t take place on the UI thread. So, in order to do this, Android provides an AsyncTask class. In Android Studio, add a new class to your app (right click on the app folder containing Main Activity, and select Add->New Class), and make sure that the new class extends AsyncTask like this:

You’ll get a basic, empty, class. Update its code to look like this:

package com.google.devrel.lmoroney.myapplication;
 
import android.os.AsyncTask;
 
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
 
import javax.net.ssl.HttpsURLConnection;
 
public class CallFCM extends AsyncTask<HashMap<String, String>, String, String> {
    @Override
    protected String doInBackground(HashMap<String, String>... params) {
        return doCall(params[0]);
    }
 
    private String doCall(HashMap<String, String> params){
 
        String response = "";
        try {
            // Replace this URL with your register script. See part 1 for details
            // http://www.laurencemoroney.com/2017/01/06/building-a-firebase-cloud-messaging-app-part-one/
            URL url = new URL("http://laurencemoroney.com/fcm/register.php");
 
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(10000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod("GET");
            conn.setDoInput(true);
            conn.setDoOutput(true);
 
            OutputStream os = conn.getOutputStream();
            BufferedWriter writer = new BufferedWriter(
                    new OutputStreamWriter(os, "UTF-8"));
            writer.write(getQuery(params));
            writer.flush();
            writer.close();
            os.close();
 
            conn.connect();
            int responseCode=conn.getResponseCode();
 
            if (responseCode == HttpsURLConnection.HTTP_OK) {
                String line;
                BufferedReader br=new BufferedReader(new InputStreamReader(conn.getInputStream()));
                while ((line=br.readLine()) != null) {
                    response+=line;
                }
            }
            else {
                response="";
 
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return response;
    }
 
    private String getQuery(HashMap<String, String> params) throws UnsupportedEncodingException
    {
        StringBuilder result = new StringBuilder();
        boolean first = true;
 
        for (Map.Entry<String,String> pair : params.entrySet())
        {
            if (first)
                first = false;
            else
                result.append("&");
 
            result.append(URLEncoder.encode(pair.getKey(), "UTF-8"));
            result.append("=");
            result.append(URLEncoder.encode(pair.getValue(), "UTF-8"));
        }
 
        return result.toString();
    }
 
    private String getPostDataString(HashMap<String, String> params) throws UnsupportedEncodingException {
        StringBuilder result = new StringBuilder();
        boolean first = true;
        for(Map.Entry<String, String> entry : params.entrySet()){
            if (first)
                first = false;
            else
                result.append("&");
 
 
            result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
            result.append("=");
            result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
        }
 
        return result.toString();
    }
 
}


This will call the registration script on your app server (see the URL, and see part one for details on how I did it), posting the instance token to it. It does it in the background as an Android Async task. Your app server now knows how to address this device.

In the third and final part of this series, I’ll show you how to add the code to your app so that, when FCM sends you messages, you can receive them and respond to them. You’ll even see how to turn them into an Android notification, so you can render them on your Android Wear device too, as happened hilariously to me at the Android Developers Summit in Berlin.

Check out the results in this video!

Site24x7 - Full stack It Infrastructure Monitoring from the cloud. Sign up for free trial.

Topics:
cloud ,firebase cloud messaging ,android app development ,tutorial ,cloud applications

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

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

{{ parent.tldr }}

{{ parent.urlSource.name }}