Friday, 25 November 2016

How to send Firebase Cloud Messaging (FCM) notification from server to client

Background

Firebase Cloud Messaging (FCM) is a cross-platform messaging solution that lets you reliably deliver messages at no cost. It is an improved version of Google Cloud Messaging (GCM). Following are some of the features that makes FCM stand out -
  1. It is cross platform so it is a natural fir for all.
  2. Using FCM you can send two types of payloads to the client
    1. Notification type in which case a notification will be directly shown on the client
    2. Data payload in which case client has to parse and act on it
  3. You can distribute message to your client app in one of the following 3 ways -
    1. Send it to a single device
    2. Send it to a group of devices
    3. Send it to devices subscribed to topics
  4. Lastly you can also send messages from client back to the server.


 I am not going to bore you with any more details here. This post is simply meant to explain server side implementation of how to deliver FCM messages to client. We will see client setup in future posts.

To view how to setup firebase project and set up a client refer -

Following in Java code to send FCM message to a single device -

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.URL;
import java.util.HashMap;

import javax.net.ssl.HttpsURLConnection;

import org.apache.http.HttpStatus;
import org.json.JSONException;
import org.json.JSONObject;


/**
 * @author athakur
 */
public class FCMMessageSender {
    
    public static final String FCM_URL = "https://fcm.googleapis.com/fcm/send";
    public static final String FCM_SERVER_API_KEY    = "<ADD_YOUR_SERVER_API_KEY>";
    private static final String deviceRegistrationId =  "<ADD_YOUR_DEVICE_REG_ID>";

    public static void main(String args[])
    {
        int responseCode = -1;
        String responseBody = null;
        try
        {
            System.out.println("Sending FCM request");
            byte[] postData = getPostData(deviceRegistrationId);
           
            URL url = new URL(FCM_URL);
            HttpsURLConnection httpURLConnection = (HttpsURLConnection)url.openConnection();

            //set timeputs to 10 seconds
            httpURLConnection.setConnectTimeout(10000);
            httpURLConnection.setReadTimeout(10000);

            httpURLConnection.setDoOutput(true);
            httpURLConnection.setUseCaches(false);
            httpURLConnection.setRequestMethod("POST");
            httpURLConnection.setRequestProperty("Content-Type", "application/json");
            httpURLConnection.setRequestProperty("Content-Length", Integer.toString(postData.length));
            httpURLConnection.setRequestProperty("Authorization", "key="+FCM_SERVER_API_KEY);

            

            OutputStream out = httpURLConnection.getOutputStream();
            out.write(postData);
            out.close();
            responseCode = httpURLConnection.getResponseCode();
            //success
            if (responseCode == HttpStatus.SC_OK)
            {
                responseBody = convertStreamToString(httpURLConnection.getInputStream());
                System.out.println("FCM message sent : " + responseBody);
            }
            //failure
            else
            {
                responseBody = convertStreamToString(httpURLConnection.getErrorStream());
                System.out.println("Sending FCM request failed for regId: " + deviceRegistrationId + " response: " + responseBody);
            }
        }
        catch (IOException ioe)
        {
            System.out.println("IO Exception in sending FCM request. regId: " + deviceRegistrationId);
            ioe.printStackTrace();
        }
        catch (Exception e)
        {
            System.out.println("Unknown exception in sending FCM request. regId: " + deviceRegistrationId);
            e.printStackTrace();
        }
    }
    
    public static byte[] getPostData(String registrationId) throws JSONException {
        HashMap<String, String> dataMap = new HashMap<>();
        JSONObject payloadObject = new JSONObject();

        dataMap.put("name", "Aniket!");
        dataMap.put("country", "India");
        
        JSONObject data = new JSONObject(dataMap);;
        payloadObject.put("data", data);
        payloadObject.put("to", registrationId);

        return payloadObject.toString().getBytes();
    }
    
    public static String convertStreamToString (InputStream inStream) throws Exception
    {
        InputStreamReader inputStream = new InputStreamReader(inStream);
        BufferedReader bReader = new BufferedReader(inputStream);

        StringBuilder sb = new StringBuilder();
        String line = null;
        while((line = bReader.readLine()) != null)
        {
            sb.append(line);
        }

        return sb.toString();
    }

}



Output :
Sending FCM request
FCM message sent : {"multicast_id":8122119840448534941,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1480094913845339%a8fa321bf9fd7ecd"}]}


You can read about various payloads you can send to various devices/device groups/devices subscribed to topics in following link -
 As for the server api key you can get it from your project in Firebase console under Setting -> Cloud messaging.







 NOTES

  • Firebase Cloud Messaging (FCM) is the new version of GCM. It inherits the reliable and scalable GCM infrastructure, plus new features! See the FAQ to learn more. If you are integrating messaging in a new app, start with FCM. GCM users are strongly recommended to upgrade to FCM, in order to benefit from new FCM features today and in the future.  
  • When I refer to client it can be an android app or Android wear (yes it is supported from Android Wear 2.0 Developer Preview)
  • For Json library I am using - <dependency org="org.json" name="json" rev="20160810"/> [Ivy dependnecy]


Related Links

No comments:

Post a Comment

t> UA-39527780-1 back to top