Grokking Android

Getting Down to the Nitty Gritty of Android Development

An XMPP Server for Google Cloud Messaging

By 104 Comments

In this post I am going to write about the server-side of upstream messages with Google Cloud Messaging. This is the second part of my three-part series on this topic. If you haven't read the first part about the flow of events and the Android implementation of upstream messaging, please read that one first. The first sections of that post are important to understand the big picture of upstream messaging and the role of the server within it.

Sample project

I have created a sample project for the server side of upstream messaging with Google Cloud Messaging. Please note that this is a sample. It's not suitable for production!

Permanent connection and XMPP

Just recall the flow of events, described in detail in my first post:

The communication model of Google Cloud Messaging with the new Cloud Connection Server
The communication model of Google Cloud Messaging with the new GCM Cloud Connection Server

For this flow to work, Google must contact your server whenever the user sends a message from his device upstream to Google's cloud. There are many models of how to do that. The one chosen by Google is to require a permanent connection between your backend and one of Google's endpoints.

That's where XMPP comes into play. Google has chosen XMPP as the protocol of choice for communicating between its servers and your server. Google named its XMPP endpoint "GCM Cloud Connection Server" or CCS for short. XMPP is an XML-based protocol that was created for instant messaging (also known under it's original name Jabber). You can read more about XMPP on Wikipedia.

Server side code

In the previous post about upstream messaging you have seen that the Android side of GCM messaging is as simple as it can get.

The server side though is another matter altogether and got more complicated with the new solution.

First of all you're most likely not as familiar with XMPP as you are with HTTP. And you're not alone with it. HTTP is probably the most used application layer protocol. Thus the online knowledge base for HTTP is huge. Less so for XMPP. You probably have to search longer for solutions when hitting a stumbling block with XMPP.

This situation also applies to libraries. While there is an abundance of HTTP libraries, there are way less for XMPP. For Java I have found only one library that is still actively maintained: The Smack library, which Google also uses in its sample code.

Luckily Google has a very detailed description of all the message types exchanged between your server and Google's cloud. And since XMPP is text-based you could build a client on your own - no matter which language you use. Nevertheless I recommend to use a library for this - after all they not only ease your life but are also more heavily tested. It's likely that others already have found a solution for a problem that would otherwise bite you in production when writing your own code.

I have taken Google's sample code for XMPP and extended it to be more flexible and suit my needs. This code requires the Smack and the json-simple libraries. To repeat: The demo is there just to get you up and running, so that you can easily test the upstream messaging model and your Android code. It's still very basic and rough!

Logging messages

When setting up the connection using Smack's XMPPConnection, you can configure it to open a Swing window displaying all incoming and outgoing messages:


config.setDebuggerEnabled(mDebuggable);

I set the flag to true when using the main() method of CcsClient. That obviously wouldn't work too well on a server so I made this configurable. From within my web project I set this flag to false.

There is another flag that configures if Smack logs every message:


XMPPConnection.DEBUG_ENABLED = true;

Within the sample code I simply set this to true to see every message. Very handy for finding problems during development and appropriate for this demo project.

Implementing a server

These are the things you have to take care of:

Since all message types are described in detail on Google's Cloud Connection Server page, you can use whatever solution you like. The following code samples are in Java and make use of the Smack library. While some stuff is from Google's sample code, some contains additions and abstractions around that sample code.

The most important class is CcsClient. This class is responsible for logging in to the server, sending messages to Google's Cloud, receiving incoming messages and handling ACKs and NACKs correctly.

Connect to the GCM Cloud Connection Server

For the permanent connection you open a TLS secured connection to gcm.googleapis.com at port 5235.

Within CcsClient the method connect() handles this. It needs a ConnectionConfiguration object.

Here's how to set up the ConnectionConfiguration:


config = new ConnectionConfiguration(GCM_SERVER, GCM_PORT);
config.setSecurityMode(SecurityMode.required);
config.setReconnectionAllowed(true);
config.setRosterLoadedAtLogin(false);
config.setSendPresence(false);
config.setSocketFactory(SSLSocketFactory.getDefault());

In the first line you specify which server and which port to use. As mentioned these have to be gcm.googleapis.com and 5235 respectively. And you have to ensure to use Transport Layer Security (TLS). That's why you have to set the SSLSocketFactory.

Afterwards you can create a Connection object and use it to establish the connection to Google's servers:


Connection connection = new XMPPConnection(config);
connection.connect();

Authenticate your server app

Google needs to ensure that you are allowed to send messages via Google Cloud Messaging - and that you are allowed to send them to the clients you are addressing. For this Google uses a project id and an API key specific for that Google Cloud project.

I have detailed in my previous post about upstream messaging how to create a project and how to generate a server API key for that project.

With XMPP you do not send the API key with every request. Instead you authenticate your server app directly after establishing the connection.

In Java just use the Connection object you created in the previous step to log in:


connection.login(mProjectId + "@gcm.googleapis.com", mApiKey);

Obviously you have to use the values created on Google's Cloud Console for mProjectId and mApiKey. You either pass them as arguments to the main() method of CcsClient or you call prepareClient() with the correct values - which I do from within my web project.

After logging in, you can send and receive messages.

Message formats

Before I will cover how to send or receive messages, I'm going to show you some typical messages sent either from your server or back to your server.

Incoming upstream messages

The following is a message as it shows up on your server when a user clicks "Register" in the Android client sample:


<message 
      to="projectId@gcm.googleapis.com" 
      from="devices@gcm.googleapis.com">
   <gcm xmlns="google:mobile:data">
      {
      "category":"com.grokkingandroid.sampleapp.samples.gcm",
      "data":
         {
         "action":
            "com.grokkingandroid.sampleapp.samples.gcm.REGISTER",
         "account":"info@openminds.de"
         },
      "message_id":"20",
      "from":"someRegistrationId"
      }
   </gcm>
</message>

This message is no different from any other message sent from an Android device. It is obvious that the message consists of an outer XML part and an inner JSON part. You can safely ignore the XML part. It's always the same and is only used since XMPP is an XML based protocol. What's important is the JSON part. The JSON object contains all the attributes you need to react appropriately to incoming messages.

All upstream messages contain the following attributes:

The attributes of a received GCM upstream message
Attribute Meaning
category Package name of the sending app
data The payload of your app
message_id A unique id you need later on to acknowledge the message
from The registration id of the device from which the message was sent

Obviously only your apps can send data to your server. But you can use the same GCM server for multiple apps. That's why the category attribute is needed.

The data attribute is where you can put all the stuff, that you want to transmit to your server. The value of the data attribute is a JSON object itself.

The registration id is sent with every message within the from attribute. It's a very lengthy string which you must use to map the data to the correct user.

ACK messages

The next section explains what's up with the ACK and NACK messages. For now, you just need to know what those messages look like.

An ACK message is the simpler of both and always looks the same:


<message>
   <gcm xmlns="google:mobile:data">
      {
      "message_id":"m-8238983812089683316",
      "message_type":"ack",
      "from":"someRegistrationId"
      }
   </gcm>
</message>
The attributes of an ACK message
Attribute Meaning
from The registration id to which the message was sent
message_id The id of the message, that is acknowledged
message_type ACK or NACK - for ACK messages obviously always "ack"

Incoming NACK messages

NACK messages come in two types. A stanza message always indicates a malformed message on your side. Stanza is the weird name used in the XMPP specification for the different kinds of XML messages that XMPP supports. Any other erroneous condition is handled by the second type of NACK messages.

Let me show you a stanza message first:


<message 
      id="iUB3B-2" 
      to="someProjectId@gcm.googleapis.com" 
      type="error">
   <error 
         code="400" 
         type="MODIFY">
      <bad-request 
            xmlns="urn:ietf:params:xml:ns:xmpp-stanzas"/>
      <text 
            xml:lang="en" 
            xmlns="urn:ietf:params:xml:ns:xmpp-stanzas">
            InvalidJson: JSON_PARSING_ERROR
                  : Missing Required Field: message_id
      </text>
   </error>
   <gcm xmlns="google:mobile:data">
      {
      "to":"someRegId",
      "delay_while_idle":true,
      "data":
         {
         "message":
               "Simple sample sessage"
         },
      "time_to_live":120000
      }
   </gcm>
</message>

The error element of the XML message contains the description of what went wrong. And the gcm element contains the complete message you have sent to the server. The descriptive error message together with the full message causing the problem makes it really simple to understand what went wrong. In this case, the message_id is missing. I won't go into detail for this type. You get those messages only, if you do not provide all mandatory attributes.

Stanza error messages should only happen while developing your app. What might follow later on are other problem types. Here is a sample message for other failure situations:


<message>
   <gcm xmlns="google:mobile:data">
      {
      "message_id":"m-4370299872608467243",
      "from":"invalidRegId",
      "error":"BAD_REGISTRATION",
      "message_type":"nack"
      }
   </gcm>
</message>

In this case the registration id you sent to Google's server is invalid. Note: You will also get NACK messages for as long as your sign-up form hasn't been processed by Google.


The attributes of a NACK message
Attribute Meaning
error A short error message
from The registration id to which the message was sent
message_id The id of the message, that is acknowledged
message_type ACK or NACK - for NACK messages obviously always "nack"

Outgoing messages to devices

The final message type is a message from your server to an Android device:


<message id="4icfN-5">
   <gcm xmlns="google:mobile:data">
      {
      "to":"someRegistrationId",
      "delay_while_idle":true,
      "data":
         {
         "message":"Test message to a registered device"
         },
      "message_id":"m-15",
      "time_to_live":10000
      }
   </gcm>
</message>

Some of the attributes for sending messages via the Cloud Connection Server are the same as with messages via Google's HTTP server. Others though are new and still others are missing. The following table shows a list of all possible attributes for sending XMPP messages to a device.

The attributes of a push message
Attribute Meaning Mandatory
collapse_key A key indicating that only the last message of this type should be sent to a device when it comes online again No
data The payload of your app No
delay_while_idle A flag indicating that messages should be kept on Google's server if the device is inactive No
message_id A unique id you need later when dealing with ACK and NACK messages Yes
time_to_live The amount of time for which Google should keep the message around if the device is offline No
to The registration id of the recipient Yes

If you have used GCM in the past you will notice the to attribute. That's the XMPP replacement for registration_ids. And in contrast to registration_ids you can send a message to only one user. Which means that for a broadcast you have to iterate over all registration ids. See Google's documentation for details.

The delay_while_idle attribute tells Google that it should not send a message when the client device is not active. A value of true means that messages are kept on Google's server until the device is active again.

The collapse_key probably needs some more explanation. If a device is offline you do not want it to get swamped with messages when it goes online again. Instead you can use the attribute collapse_key to ensure that only the last message for this key gets delivered to the app. But note: You can use only four collapse keys at the same time. The collapse_key applies to messages not delivered right away because of an delay_while_idle flag, but also to messages than cannot be delivered because the device isn't connected at all.

You might have noticed that the data attribute is optional. Now at first this might sound like a pointless exercise. Why send a message without any data in it? But it depends on the purpose of the message. You can use a GCM message as a tickle. To simply notify your app, that there's new data on the server to download. Unless the app can download different types of data, an empty message would be enough. When such a message arrives, your app would try to contact your server and download what it has to know.

If you do not set a time_to_live value, the default is used. The default currently is four weeks.

Message acknowledgements

The GCM Cloud Connection Server expects your server to acknowledge each and every method it sends to you. Google states explicitly that you should never send a NACK!

Always having to acknowledge messages means you should be able to deal with those messages. Take care of exceptional conditions, that might come up at your end. Google will resend messages for which you fail to send an acknowledgement. So not acknowledging puts unnecessary burden on your server.

Here's what Google expects your server to adhere to:

For each device message your app server receives from CCS, it needs to send an ACK message. It never needs to send a NACK message. If you don't send an ACK for a message, CCS will just resend it.

Source: https://developer.android.com/google/gcm/ccs.html

Google sends back ACK or NACK messages for every message your backend sends towards Google's cloud. Google obviously is allowed to send NACKs. A NACK coming from Google means that you did something wrong - most of the time at least. For example you will get NACK messages for trying to send messages to registration ids that aren't valid anymore.

Google will also send NACKs if the service is down or in case an "Internal Server Error" occurred. In the first case you should simply queue the message to resend it sometime later. In the second case though, you are a bit on your own. Most likely resending should be fine since most other cases are handled with other exception codes. So most likely it's a problem on Google's end - but you cannot know for sure. Maybe the problem is caused by the content of your message after all. It might be a good idea to add an internal retry counter which you decrease with every transmission. At the very least log those cases and have a look at them.

Receive messages from Google's cloud

To handle incoming messages with Smack, you first have to register a PacketListener object with the Connection you created in the first step above. This object is responsible for all incoming traffic. See this slightly adapted version of Google's code:


connection.addPacketListener(new PacketListener() {
   @Override
   public void processPacket(Packet packet) {
      Message incomingMessage = (Message) packet;
      GcmPacketExtension gcmPacket =
            (GcmPacketExtension)incomingMessage
                  .getExtension(GCM_NAMESPACE);
      String json = gcmPacket.getJson();
      try {
         Map jsonMap =
               (Map)JSONValue.parseWithException(json);
         
         handleMessage(jsonMap);
      } catch (ParseException e) {
         logger.log(Level.SEVERE, "Error parsing JSON " + json, e);
      } catch (Exception e) {
         logger.log(Level.SEVERE, "Couldn't send echo.", e);
      }
   }
}, new PacketTypeFilter(Message.class));

And handleMessage() looks like this:


private void handleMessage(Map<String, Object> jsonMap) {
   // only present for "ack"/"nack" messages
   Object messageType = jsonMap.get("message_type");
   if (messageType == null) {
      // Normal upstream data message
      CcsMessage msg = getMessage(jsonMap);
      handleIncomingDataMessage(msg);
      // Send ACK to CCS
      String ack = createJsonAck(msg.getFrom(), msg.getMessageId());
      send(ack);
   } else if ("ack".equals(messageType.toString())) {
      // Process Ack
      handleAckReceipt(jsonMap);
   } else if ("nack".equals(messageType.toString())) {
      // Process Nack
      handleNackReceipt(jsonMap);
   } else {
      logger.log(Level.WARNING, "Unrecognized message type (%s)",
      messageType.toString());
   }
}

The PacketListener has just one method: processPackage() which takes a Packet as argument.

A data package - that is an upstream message coming from a device - is then delegated to handleIncomingDataMessage(). For my sample project I have modified Google's original code quite a bit. For one I use a CcsMessage object here that represents the incoming message.

Next I use PayloadProcessors to deal with the different type of messages. For every possible type of message I have a specific implementation of this interface to actually deal with the incoming message. You can of course replace this logic with whatever suits you.

What you do within those PayloadProcessors is very app-specific. The sample code just provides very basic implementations to give you an understanding of how to deal with messages. Hopefully your app has more to offer than my sample 🙂

Send messages to Google's cloud

To send a message to Google's Cloud Connection Server, you have to follow these steps:

  1. Create the JSON payload
  2. Create a Smack Packet for the message
  3. Send the XML message to Google's cloud

Create the JSON payload

With json-simple you can create a JSON object from is a map by calling JSONValue.toJSONString(). Each key of the map corresponds to one JSON attribute. In the section about message types I have listed the possible attributes. With this you can first create the map:


public static Map createAttributeMap(
      String to, 
      String messageId, 
      Map<String, String> payload,
      String collapseKey, 
      Long timeToLive, 
      Boolean delayWhileIdle) {
   Map<String, Object> message =
         new HashMap<String, Object>();
   if (to != null) {
      message.put("to", to);
   }
   if (collapseKey != null) {
      message.put("collapse_key", collapseKey);
   }
   if (timeToLive != null) {
      message.put("time_to_live", timeToLive);
   }
   if (delayWhileIdle != null && delayWhileIdle) {
      message.put("delay_while_idle", true);
   }
   if (messageId != null) {
      message.put("message_id", messageId);
   }
   message.put("data", payload);
   return message;
}

Using this method creating a JSON string for sending a message is simple:


public static String createJsonMessage(
      String to, 
      String messageId, 
      Map<String, String> payload,
      String collapseKey, 
      Long timeToLive, 
      Boolean delayWhileIdle) {
   return createJsonMessage(
         createAttributeMap(
               to, 
               messageId, 
               payload,
               collapseKey, 
               timeToLive, 
               delayWhileIdle));
}

public static String createJsonMessage(Map map) {
   return JSONValue.toJSONString(map);
}

Create a Smack Packet for the message

Creating a Packet object is even simpler. Google's code makes use of the extension mechanism of Smack. Smack's extensions are handlers for specific message types. The code uses them for processing incoming as well as outgoing messages.

Google's inner class GcmPacketExtension is an implementation of Smack's PacketExtension interface.

It's method toPacket() creates an XML Packet, in this case it wraps the JSON with appropriate XML as required by XMPP.


Packet request = new GcmPacketExtension(jsonRequest).toPacket();

Send the message to Google's cloud

If you have a Packet object you simply call send() on your XMPPConnection object that you created connecting to Google's server in step one.

My demo follows Google's sample code in combining the last two steps in the method send() of the CcsClient class:


public void send(String jsonRequest) {
   Packet request = new GcmPacketExtension(jsonRequest).toPacket();
   connection.sendPacket(request);
}

Sending to multiple recipients via Google's Cloud Connection Server

You cannot send a message to multiple recipients when using Google's Cloud Connection Server. Instead you have to send one message for every registration id you want to send a message to. That's why I added the message sendBroadcast() which simply iterates over all recipients:


public void sendBroadcast(Map<String, String> payload, String collapseKey,
      long timeToLive, Boolean delayWhileIdle, List<String> recipients) {
   Map map = 
         createAttributeMap(null, null, payload, 
         collapseKey, timeToLive, delayWhileIdle);
   for (String toRegId: recipients) {
      String messageId = getRandomMessageId();
      map.put("message_id", messageId);
      map.put("to", toRegId);
      String jsonRequest = createJsonMessage(map);
      send(jsonRequest);
   }
}

Note: There actually is one option to target multitple registrations ids with just one message. With user specific messages you can target all devices of one user. But you're still limited to one user only with this option. Since I'm going to cover user specific messages in my next post, I won't deal with this option here.

You can combine HTTP and XMPP

Google allows you to use HTTP at the same time as XMPP to send messages to devices. It's up to you if you want to use XMPP just to receive upstream messages of devices and to acknowledge those messages or if you want to use XMPP to talk to Google's Cloud Connection Server (CCS) for everything.

Actually there is one use case for which you have to use HTTP - at least at the moment. I very much hope that this will change when the final version of those new services is released for everyone. I will cover that specific use case next week.

One final thing

I have written most of the server code in preparation of my talk at the Dutch Android User Group meetup. As I have written in my previous post about Google Cloud Messaging, you have to sign up to use the new features like upstream messaging, XMPP or user notifications. After signing up, Google processes your request and some time later comes back with the approval. In my case the approval took a while and the preparation for the talk was in jeopardy.

Gladly Dennis Geurts offered to use his testing API key and project id for which he had signed up much earlier. A big thanks for that, Dennis!

Lessons learned

With this post I have shown you some aspects of the server side of Google Cloud Messaging using the new upstream messaging model.

You have seen the different message types, have heard of the need to acknowledge messages and how to receive and send messages using Smack's Java library for XMPP. Since XMPP is text based those code snippets should be easy to transform to any other language.

Together with the source of the demo project this post should get you on the right track to set up your own project.

If you want to start using Google Cloud Messaging, be sure to read the official documentation. I couldn't cover all in this post. Be sure to not forget the document about advanced topics. There is also a nice blog post by Ryan Oldenburg of Pushbullet about some thinks to keep in mind when using GCM. It might help you to avoid problems right away. For another perspective on the topic you might also want to read Antoine Campbell's Cloud Connection Server Tutorial.

One final problem: Right now I don't know any SaaS or BaaS provider to support the XMPP messaging model for Google Cloud Messaging. This is a serious limitation in my opinion - one which I expect to get much better when this model gets adopted more often and is published to all without approval process. Should you know of any provider supporting the new GCM model, please drop me a line.

Wolfram Rittmeyer lives in Germany and has been developing with Java for many years.

He has been interested in Android for quite a while and has been blogging about all kind of topics around Android.

You can find him on Google+ and Twitter.

104 thoughts on “An XMPP Server for Google Cloud Messaging”

  1. Thank you again Wolfram, looking forward to the last installment.

    BTW, we’re going on a couple of weeks now waiting for Google XMPP approval. How long did it take for your approval?

    1. It took Google about two weeks to approve. But I applied at the beginning of the year. The backlog probably was quite low then because of (nearly) no one applying around Christmas and New Year’s Eve.

      Because it’s for my demo and my the talk preparation, I selected the lowest “Active User” estimate possible, though. I would expect all other numbers to be processed faster.

  2. I try this (just to test connection):

    public static void main(String[] args) {

    ProxyInfo proxyInfo = new ProxyInfo(ProxyInfo.ProxyType.HTTP, PROXY_HOST, PROXY_PORT, “”, “”);

    ConnectionConfiguration config = new ConnectionConfiguration(GCM_SERVER, GCM_PORT,proxyInfo);
    config.setDebuggerEnabled(true);
    config.setSecurityMode(SecurityMode.required);
    config.setReconnectionAllowed(true);
    config.setRosterLoadedAtLogin(false);
    config.setSendPresence(false);
    config.setSocketFactory(SSLSocketFactory.getDefault());

    XMPPConnection.DEBUG_ENABLED = true;

    Connection connection = new XMPPConnection(config);
    try {
    connection.connect();
    } catch (XMPPException e) {
    e.printStackTrace();
    }

    }
    but i get only
    gcm.googleapis.com:5235 Exception: XMPPError connecting to gcm.googleapis.com:5235.; : remote-server-error(502)

    Any idea?

    1. Not really. I have tried to use it using a proxy once and failed as well. If I recall it correctly I have read somewhere that the Smack proxy support only works for XMPP via HTTP. XMPP via HTTP would be valid if both sides agree to do that. But Google doesn’t support that AFAIK – and I think this makes sense. Otherwise: Why choose to use XMPP in the first place?

      But I’m on very shaky ground here. So maybe you can get it to work. If you do so, please let us know! I’m quite sure there are plenty of kindred devs who would love to find a solution for this. After all this probably is the usual setup in corporate environments.

  3. I tried your code.
    But when i try to connect

    connection = new XMPPConnection(config);
    connection.connect();
    I get the following error
    gcm.googleapis.com:5235 Exception: XMPPError connecting to gcm.googleapis.com:5235.; : remote-server-error(502)
    — caused by: XMPPError connecting to gcm.googleapis.com:5235.: remote-server-error(502) XMPPError connecting to gcm.googleapis.com:5235.
    — caused by: java.net.ConnectException: Connection timed out: connect
    at org.jivesoftware.smack.XMPPConnection.connectUsingConfiguration(XMPPConnection.java:592)
    at org.jivesoftware.smack.XMPPConnection.connect(XMPPConnection.java:1010)
    at CcsClient.connect(CcsClient.java:348)
    at CcsClient.main(CcsClient.java:452)
    Nested Exception:
    XMPPError connecting to gcm.googleapis.com:5235.: remote-server-error(502) XMPPError connecting to gcm.googleapis.com:5235.
    — caused by: java.net.ConnectException: Connection timed out: connect
    at org.jivesoftware.smack.XMPPConnection.connectUsingConfiguration(XMPPConnection.java:565)
    at org.jivesoftware.smack.XMPPConnection.connect(XMPPConnection.java:1010)
    at CcsClient.connect(CcsClient.java:348)
    at CcsClient.main(CcsClient.java:452)
    Nested Exception:
    java.net.ConnectException: Connection timed out: connect
    at java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.net.PlainSocketImpl.doConnect(Unknown Source)
    at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
    at java.net.PlainSocketImpl.connect(Unknown Source)
    at java.net.SocksSocketImpl.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.connect(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.(Unknown Source)
    at com.sun.net.ssl.internal.ssl.SSLSocketFactoryImpl.createSocket(Unknown Source)
    at org.jivesoftware.smack.XMPPConnection.connectUsingConfiguration(XMPPConnection.java:557)
    at org.jivesoftware.smack.XMPPConnection.connect(XMPPConnection.java:1010)
    at CcsClient.connect(CcsClient.java:348)
    at CcsClient.main(CcsClient.java:452)
    Exception in thread “main” java.lang.IllegalStateException: Not connected to server.
    at org.jivesoftware.smack.XMPPConnection.sendPacket(XMPPConnection.java:483)
    at CcsClient.send(CcsClient.java:171)
    at CcsClient.main(CcsClient.java:464)

    I am using smack library 3.4.1
    Please help me how to resolve this.

    1. Wolfram Rittmeyer

      How do you connect? Directly or via Proxy? Many problems can crop up in corporate networks, since firewalls might block access to the rather unusual port or proxies might interfere with any outgoing traffic. The exception indicates a networking problem on your part – it’s simply getting a timeout. I guess neither Google nor your provider are the problem here 🙂

      Check your setup and any firewalls (corporate or personal) between you and the outer internet.

      1. I connected directly without any proxy. Thanks for the reply.

        I will try to fix that.

  4. I can’t find the org.v1.xmlpullparser refrence in CcsClient..?? its for android devices not for server

    1. Wolfram Rittmeyer

      This class is part of the binary download of the smack library. It’s necessary for the server!

      You can find the sources and the documentation on the XML Pull Parsing website.

  5. another thing ur CcsClient uses connection = new XMPPConnection(config); but it says cannot instantiate XMPPConnection

    1. Wolfram Rittmeyer

      This has changed with Smack 3.4.x. The sample is based on Smack 3.3.1. With the newer library you have to use TCPConnection instead.

  6. Connection connection = new XMPPConnection(config);
    is uninstantiable

  7. Thanks for publishing this tutorial!
    I understand everything you have written and also xmpp. But the void for me is how to package your server java code into an actual working server. The Android docs also stopped short of that for CCS (but not for HTTP).

    how to I package your server project into something that actually works?
    TIA
    Dean

    1. I’ve the same problem too!
      If it had been a servlet it would have been obvious but with just java classes I can’t really understand how to deploy it

      Any explanation woult be great!

      Thanks

    2. Wolfram Rittmeyer

      Think of this as some kind of library. You just prepare the client somewhere in your code and are good to go. Of course you would have to make CcsClient more robust to cope with connection loss and the like and you would have to provide a real persistence solution instead of the dummy in-memory one I use.

      @Alberto: I actually tested my code using a standard Java EE Web app with Servlets and (cough) JSPs. I plan to release this as part of the testing app as well – but right now I have other priorities.

      1. Sounds like this technology is embryonic.

        My android apps use internal SMS to communicate between phones and then KitKat broke that up. I was looking at this XMPP as a replacement for that but if it’s not ready, it seems we have a technology hole?

        1. Wolfram Rittmeyer

          I expect Google to change it slightly after the trial period. But as with Cloud to Devive Messaging which ended up as Google Cloud Messaging, the transition between the current form and the final form should be easy enough.

          If you want to enable user specific notifications and notification cancellation, I think Google Cloud messaging and applying for this new mode is the way to go.

          1. I ended up using GCM HTTP. It works reliably and it is very quick – very often within a second or two. Surely fast enough for a messaging app. Maybe not fast enough for a Walkie – talkie app.
            Dean

        2. Wolfram Rittmeyer

          BTW: For user notifications you do not necessarily need an XMPP based backend yourself. Expect more about that in my next post.

          1. For implementing user notifications on XMPP, is there sample code anywhere on the web? I have been trying to implement an XMPP server with User Notification support but, have’nt figured out the format for creating/updating/deleting a notification key. Sending and receiving messages worked fine. Even the official documentation does’nt help too much. Thanks in advance.

  8. Hi,

    I got my project ID whitelisted. I am able to send message to the device using your server code. However when the client sends a message using the same project id, I am not able to receive it on the server end.

    There is not log being printed and the ack or nack is also not received by the device.

    Please provide any suggestion to resolve the issue, I am struck at this point.

    Thanks,
    Kris

    1. Wolfram Rittmeyer

      How did you get the registration id of your device to the server? While writing this and the preceding post I used upstream messaging for this as well. Did you transmit it via HTTP instead? And which version of Play Services are you using?

      1. Thanks for the reply.

        I have a HTTP request to register the GCM id in the server when the user logs into the App.

        As I was not able to proceed further with Upstream messaging, temporarily I tried using HTTP to send the chat message to the server and then using XMPP to forward that to client.

        We are using play services version 16 and com.google.android.gms.version is 4323000.

        1. Wolfram Rittmeyer

          See this SO thread: In this case the reason was multiple deployment of the web app causing problems. Could this be your problem as well?

          1. I handled the single instance problem few days back. I just started the server once with Debug mode enabled and then all of a sudden things started to work. Seems very strange but I have it working now. Thanks a lot for the Debug mode suggestion.

  9. Hi.

    I’ve implemented GCM CCS myself. Downstream messages work as expected. Unfortunately, upstream messages are not received on the server, although they seem to be sent just fine from the client side. Using Glassfish and initializing the XMPP connection inside a servlet. ACKs for downstream messages are being received.

    Seems that I have the same problem as Kris. Might there be a temporary problem with GCM servers ?

    Stack Overflow post for reference: http://stackoverflow.com/questions/23366588/gcm-ccs-server-implementation-not-receiving-upstream-messages

    Thanks,
    Bogdan

    1. Wolfram Rittmeyer

      I will check if this still works as expected this weekend.

      1. Hello again, Wolfram.

        I’m still having the stability issues that I described in the StackOverflow chat, with no luck figuring out what’s wrong… now I’m trying to get the debugger set up in order to maybe see more info from it. Unfortunately, every time I enable the debugger with (config.setDebuggerEnabled(true);), I get:

        java.lang.IllegalArgumentException: Can’t initialize the configured debugger

        Have you encountered this or do you have any idea what’s causing it ? I’ve tried both using Smack v3.2.1 and Smack v4.0.0-rc2.

        Thanks !
        Bogdan

  10. hi!
    I’ve implemented GCM CCS myself,but it login error,I am sure my username and password is correct,how to resolve it,or it Instable itself?

    SASL authentication PLAIN failed: text:
    at org.jivesoftware.smack.SASLAuthentication.authenticate(SASLAuthentication.java:342)
    at org.jivesoftware.smack.XMPPConnection.login(XMPPConnection.java:243)
    at org.jivesoftware.smack.Connection.login(Connection.java:368)
    at com.taobao.wireless.gcmagent.SmackCCSClient.connect(SmackCCSClient.java:391)
    at com.taobao.wireless.gcmagent.SmackCCSClient.main(SmackCCSClient.java:426)

    1. X-OAUTH2X-GOOGLE-TOKENPLAIN
      Project xxxx not whitelisted.

      1. Wolfram Rittmeyer

        As I’ve written in my first post about Google Cloud Messaging with the new Upstream Messaging model, you have to sign up first. You’ll get a mail by Google some time later – and only then can you use upstream messaging and XMPP.

        See the section “Sign up for using the new features” in my first post.

    2. Wolfram Rittmeyer

      You have to set the correct security mode on your ConnectionConfiguration object and use the SSLSocketFactory.

      See the sections “Connect to the GCM Cloud Connection Server” and “Authenticate your server app” of this post.

  11. Hi,

    Firstly, Thanks a lot for making this GCM Upstream messaging much easier to understand.
    I have followed your code for Android client side. For making the server I have a php developer
    to work on it. I showed him the server code but he is not able to understand the Java code. Is there
    anything you know about making this server using php, please do help me. Any link or any blog will be
    much helpful.

    Kind Regards
    Aftab Saraz

    1. Wolfram Rittmeyer

      Well apart from the library specifics there is nothing special. I think any developer should be able to at least understand code in other languages – unless they are too obscure.

      Anyway: He either has to look for an XMPP library for PHP first or he could implement everything based on the XML/JSON mix that I have described in detail. The protocol is text-based so you can easily implement it yourself in whatever language you (or in this case your developer) likes. I nevertheless recommed to use a library as I have written in my post.

      1. Thanks for the quick reply. Forwarding your reply to the php developer.

  12. Hello,

    That configuration should have the server side to install the SmackCcsClient
    It can be used in some hosting? which recommend use?

  13. Can I use parts of your code for my app?

    1. Wolfram Rittmeyer

      Yes, you can. Of course it would be nice to give credit in the about section of your app and to mention it on social networks 🙂

      Please drop a link to your app, when it’s done.

      1. hi sir
        i want to implement an app which sends upstream to chrome extension can i achieve that goal by using this codes ? o.o
        i am new to programming :_:

        1. It doesn’t matter which GCM model you use, all communication in this case would have to go through some kind of backend – unless you use topic groups (https://developers.google.com/cloud-messaging/topic-messaging). Your backend then would dispatch incoming messages to the kind of clients that are interested in them (in your case to all the extensions that should be addressed).

          Given that I know only very little of what you actually want to do, I’d say it is possible. But it needs quite some thinking as to who (which Android device) can send upstream to which extensions (that is which specific instances of your extension) and how to manage these relationships.

          1. android app will send upstream data of pull notifications to chrome extension (its user specific ) just like Desktop Notifications app my concept of my app is same as Desktop Notifications reading notification bar notifications from chrome extension this is my aiim .

  14. it works perfect but i have one problem when i run the app
    it runs main and sends a message to the device and then stops,
    if i turn on the smack debugging it opens a window and runs as a server stays running
    after it sends the message, i need this to run in the console with no window so how
    do i make it to run like a server without the debugging window??? please help

    Ryan

    1. Wolfram Rittmeyer

      You can user the prepareClient() method to use it from any other Java code (e.g. servlets, or whatever suits you best). I have described this briefly in the README file of the github project.

  15. Sir,
    I read your post. But still m not getting the clear idea about GCM. We have to create our application server and run it continuously right?

    Thanks,
    OnK

    1. Wolfram Rittmeyer

      Yes, otherwise Google cannot send you any upstream messages. A short downtime is okay, but after a while Google discards messages.

  16. Hello Wolfram,
    Please I need your help,
    I think I didn’t understand something…
    In all the examples about using GCM XMPP Server (Including in Google android site and in your code also) I see that the XMPP connection is not up for a long time .. only few seconds until the main() function is over ..
    Am I right?
    Isn’t the idea is to make the app-server to listen on this connection and to get messages from users and to pass it to other users?
    Am I missing something?

    Please help …
    Searched all over the web.
    Thanks !

    1. I don’t usually use the main() method, instead I use prepareClient(). But in either case the connection stays alive. Another Thread gets spawned that keeps on living even if main() has finished.

      So your assumption about the XMPP client is correct. Listening to incoming messages is exactly what the code is supposed to do.

      1. Thanks for your fast answer 🙂

        In eclipse when I run the code so it terminates after few seconds and I don’t see process running in the background in my computer … I am almost sure that everything is closed after main is finished.

      2. Hey, thanks for your fast answer.
        How can I see there is another thread working in the background? it’s not make scence because the program terminates and also I dont see that the proccess in the proccess list holds.

        1. Hi, first thanks for your clear explanation.

          I implemented the GCM as it was written in android tutorial. It’s pura java, no PHP.

          I’m not receiving upstream messages and I suspect that as the program dies, the server is no longer listening.

          How I supposed to keepo the connection with gcm opened?

          Is the deployement into an application server a must in order to keep the connection opened? is there any way to do it by using pure java?

          Thanks!

          1. Of course you can use pure Java. Every other Java based server (including all application servers) in the end are pure Java as well. But if you do so, you have to monitor carefully to know when your code died for whatever reason. And to be able to quickly restart. Google keeps messages around for a while, so this would not be a big issue – unless a quick response time is of the essence.

  17. Hi, nice explanation of the google’s example.

    Nonetheless, when I try to print the port with getPort() of the XMPPConnection object the port is 0. Is this normal?? Also when I call the isConnected() method from the same XMPPConnection object I get a positive answer which meant that I am connected with the Google’s XMPP server.

  18. Hello.
    Great blog and clear explanation – very helpful.
    I’ve investigated a little bit and I think there is NO way to detect if an android device is online using GCM because app server communicate with Google’s servers. Am I right? I need to know that for my future project.
    Thanks.
    Best regards.

    1. You need this on the server side? What for?

      But, yes, you do not know if the recipient will get the message, but if you enable delivery receipts you know after the fact if the user got the message.

      If you are afraid that data will be obsolete when the GCM message finally arrives, you can set the time to live to a very low value – thereby ensuring that only devices that currently are connected get the message.

      1. Thanks for your answer.
        Yes, I need that on the server side. Let’s say the project has 2 user types: type A and type B. User type A needs to see on her/his android device which users of type B is nearby and then selects one of them to request a service. But if selected user type B is not online then user type A will know that after message time to live exceed. That’s ok. But it may happen for couple of selected user type B in a row. So user type A will be annoyed because can’t find what she/he is looking for in a couple of taps. That’s why I need first to check if user type B is online and then send (push) message. I assume I need to workaround the problem somehow – for example: use app server to receive small amount of data from user type B’s android device in some period.

        1. I guess the app gets the list by your server anyway. So why not do it like that:

          Send all type B users a ping and request a receipt
          Send the full list to specific client that requested the list
          Client displays list with an icon for “online status not yet known”
          Server sends periodically update notifications to requesting client with all type B users that confirmed the ping in the meantime
          Client updates list with a green status for these type B users
          After TTL is over server sends a list to the client with the remaining type B users
          Client updates list with red status for those type B users

  19. Thank you, sir.
    Your idea is very useful. I will try to implement it.
    Best regards.

  20. Do we need Xmpp server to implement for this gcm or any server can deal with it?

    1. You need to open a connection to Google’s XMPP server and keep this connection open. How you do that is up to you. You do not necessarily need a special server for that.

      Keep in mind that you still can use GCM via HTTP. XMPP is just an alternative!

  21. am stuck in using the smack library….i downloaded the latest version but importing some packages become a problem please guide me on how to use smack library

  22. Hello, thanks for a great tutorial.

    I’m just wondering if its even possible for this to work on Google App Engine with android. The smack library opens socket connections and I don’t think Google App Engine allows that.

    1. Wolfram Rittmeyer

      I have not tried that yet. I think it’s not possible yet, but I’m not sure. Please let me know if you find out that that’s not correct.

  23. i did connection with gcm and i was able to send message from server to android client .. but it took around 3 or 6 secs to reach android … but when i did without gcm (i.e) with the help of only openfire it took less than 1 secs to reach android client .. y so ?? is gcm so slow ?

    1. Wolfram Rittmeyer

      No idea what’s wrong here. From my experience GCM usually is very fast.

  24. is there xmpp server using message broadcasting?

    1. GCM CCS (XMPP) doesn’t allow the broadcasts of messages. In order to do that, you have to manually send the messages one by one to the receiver.

  25. Can you guide me where we can host our server. Google App engine not support xmpp connection .right?

    1. Wolfram Rittmeyer

      No, not really. I do not know of any option other than hosting yourself.

      I still expect Google to provide a way eventually, but as far as I know, they haven’t done so, yet.

      1. thanks for reply. i’m developing an app send information of user to another user. i done with Http connection. it work good. but now i want to implement xmpp ccs for replace. i’m amateur so i just search imformation online. thanks for reply

    2. You could try DigitalOcean. I have already deployed a CCS proiect there. Cool guys.

      https://www.digitalocean.com/?refcode=1d8fc8f19544

      1. thanks for your guide 🙂

  26. Thanks for the detailed tutorial. I should have found this tutorial before I went head with PHP/XAMPP(installed in my machine) because there was no tutorial like this at the time. I have 2 android apps which communicate on GCM I want to deploy my apps on third party server but I couldn’t find one. Where can you direct me? Is there a better way to do it? I am also not using the testing port, but the old way send the test/production to the same url. Feel free to email me. Thanks so much.

  27. @Wolfram Rittmeyer, I’m not sure if I can retrieve upstream messages sent from Android while my server (XMPP-client) was unreachable (like network shortage or server maintenance). All upstream messages sent while my server is down are not resent when the server is up again (reconnected with GCM thru XMPP).
    Can you shed any light over this case?

    1. Did you fix it?I have the same problem

  28. Thank you very much Rittmeyer! This tutorial is simply great and also very unique as no other tutorial explains the serverside gcm ccs to this extent.
    I wonder what you used(physical server/server structure/testing environment/etc.) when writing the serverside code. Just wondering if there are better solutions than what I am currently using to achieve gcm ccs – Apache Tomcat on a google cloud compute engine vps.

  29. Hey Wolfram!
    Firstly, I’d like to thank you immensely for imparting such an in-depth knowledge of the GCM to us! I’m really thankful! Well, what I wanted to ask you was this:
    I have an application that is going to harness GCM’s XMPP connection and send bidirectional messages (actually, location coordinates). The new GCM API documentation, however, uses InstanceID and a lot of the methods you’ve used here are deprecated.
    I was able to build my XMPP server from scratch, but I have no idea how I should deploy it! (Oops)
    How do I run the XMPP server? Could you please guide me?

    1. Hm, not sure what your problem is. If you built a server from scratch and it works locally there should be some way to wrap it up and run somewhere else. The only thing to consider is to open up the necessary ports so that no firewall blocks access to and from Google’s servers.

      What you should consider are health checks that ping your server to find out if it’s still alive. And that are able to restart the server if necessary.

      What specifically is your problem?

      1. Hey Wolfram! Thanks for the prompt reply!

        I’m designing an application that uses GCM so as to realize the real-time geo-coordinates of other users in a specific group. I built my XMPP server making use of the the Google Sample code (and your’s too, obviously), but I don’t know how to host the server (either globally or locally). I read about hosting the XMPP server locally on Tomcat, but I don’t know how to do it. :/

        1. There’s no need for Tomcat – unless you want to combine it with a Java Servlet Application. It would suffice to use a simple jar file. You’re opening the connection from within your Java code.

          Depending on the load, uptime requirements and so on, that might not suffice. But that’s the same as with any backend solution.

  30. Hi Wolfram
    thanks for this great article
    I am really new in server side programming (just a little C# visual studio)
    so my questions is:
    which ide should I use to compile and test your code? can I use visual studio?
    and wich type must be my host “windows, Linux”

    1. You can build your backend with any IDE you like and in any language you like and host it on any operating system you like. The protocol is text based so it should be easy enough to adapt the code to C# for example.

      If you want to use the above code, I recommend to use a Java-IDE. I happen to use Android Studio for Android development and Netbeans for backend development (not necessarily tied to Java). But if Visual Studio supports Java, then go for it. I use Linux for development and prefer to use it for my backends as well. But Java runs fine on most operating systems and definitely does so on Windows.

  31. hi dear wolfarm,
    i wanna to make a program that is like a chat program,with might milions of users.
    is GCM ok for such program?
    can i use nodejs for serverside?
    Has GCM any limits?
    thanks

  32. Hey Wolfram! I created the XMPP Server, but I have a few nagging doubts. Here they are –
    1) I created a Runnable JAR file for the Java Application. My question is – Will this suffice if I want to use my XMPP Server globally? Or do I need to deploy this JAR file onto some Third party cloud server (OpenShift)?

    2) In my Server code, I want the server to wait for a certain amount of time so that clients can register themselves and upload the necessary data to the server AFTER WHICH the server can compute some data based on the uploaded content. How do I make the server wait for a certain amount of time?

    3) I’d really, really like your feedback on my code. Would you provide your e-mail ID to me? I’d like to send you my Server side code, and I’ll be more than happy to receive any kind of feedback from you.

    Cheers, Rahul.

    1. Wolfram Rittmeyer

      There’s no need to physically distribute your server. You communicate with Google’s endpoint not clients all over the world. But you should ensure that it’s up. For this Cloud solutions are probably better suited than something else.

      With the CCS / XMPP model your server is up all the time and waits continuously for upstream messages. Not sure what you mean by “wait for a certain amount of time”. Just wait for incoming registrations and then do whatever you want to do in reply to those registrations. You can send to registrations ids individually or to groups (topics or device groups).

      I cannot do a code review for free. I’m sorry.

  33. Hi Wolfram,
    Thnx for such an awesome tutorial. I have got one question.
    To create an Xmpp app server, do I need to create a J2EE web project using smack library and deploy it in tomcat ?

    If not then plz let me know how to create this backed server.

    Really stuck with this xmpp server thing, implemented rest.

    Thanks in advance.

    1. Wolfram Rittmeyer

      How to integrate your XMPP part depends very much on what you use for other parts of the system and how you want to integrate those parts. It’s not necessary to integrate your XMPP server with Tomcat (and probably against container guidelines for full fledged Java EE servers). Keep in mind that you must keep the connection open.

  34. I am a C# developer and I want an XMPP library to use in my code to connect to GCM CCS.
    I’ve tried many libraries, but couldn’t establish a connection to the server, all libraries which I’ve used display error although all parameters are the same as in your example.
    Could you please tell me if you have a library as Smack to work with it on C# environment.
    However, thank you very much for this article.

    1. Wolfram Rittmeyer

      No. I do not use C# and thus am not familiar with libraries in that area. But I bet that there are multiple libraries that exist for C#.

      Also keep in mind, that XMPP is a text based protocol on top of TCP – so you should be able to do everything on your own. Sure, libraries in general are the better solution (if they have a proper user base they most likely are better tested and used in lots of weird circumstances), and you get results faster that way, but it is possible to get this to work without one.

  35. Hi Wolfram, my XMPP server was down for few minutes, but all upstream messages sent at that moment were not recovered after server was running. Is not possible to retreive those messages? Is not the same concept as downstream messages?

  36. Hi Wolfram. Thanks a lot for your tutorial. Have you managed to change from GCM to FCM yet?

    1. Wolfram Rittmeyer

      No, I haven’t moved to FCM yet. Actually I just had a cursory glance at it. But I plan to do a blog post about it – after all this blog needs some fresh life. That would be a good topic for this.

      1. Hi Wolfram, my XMPP server was down for few minutes, but all upstream messages sent at that moment were not recovered after server was running. Is not possible to retreive those messages? Is not the same concept as downstream messages?

      2. Hi Wolfram, Thanks for the nice post. I am trying to make this work for FCM but having issues in authentication itself. Any pointers for successful migration would be much appreciated.
        Regards,
        Irshad

        1. I have set this up using FCM without any problems. You can see my instructions here: http://stackoverflow.com/a/38170310/4433653

        2. Hi Irshad,
          For fcm everything is same just u need to change urls
          private static final String GCM_SERVER = “fcm-xmpp.googleapis.com”;
          private static final int GCM_PORT = 5235;

          public void connectToServer(String senderId, String apiKey)
          throws XMPPException, IOException, SmackException, Exception {
          if(connection==null)
          {
          XMPPTCPConnectionConfiguration config = XMPPTCPConnectionConfiguration
          .builder().setServiceName(GCM_SERVER).setHost(GCM_SERVER)
          .setCompressionEnabled(false).setPort(GCM_PORT)
          .setUsernameAndPassword(senderId + “@gcm.googleapis.com”, apiKey)
          .setCompressionEnabled(false)
          .setConnectTimeout(30000)
          .setDebuggerEnabled(true)
          .setSecurityMode(SecurityMode.disabled).setSendPresence(false)
          .setSocketFactory(SSLSocketFactory.getDefault()).build();

          connection = new XMPPTCPConnection(config);
          }
          if(!connection.isConnected())
          {

          // disable Roster as I don’t think this is supported by GCM
          Roster roster = Roster.getInstanceFor(connection);
          roster.setRosterLoadedAtLogin(false);

          logger.info(“Connecting…”);
          connection.addConnectionListener(new LoggingConnectionListener());
          // Handle incoming packets
          connection.addAsyncStanzaListener(this, this);
          // Log all outgoing packets
          connection.addPacketInterceptor(new MyStanzaInterceptor(), this);
          connection.connect();

          connection.login();
          }
          }

    2. I made a fork with the necessary migrations to use FCM with additional modifications, such as, use Moshi for JSON parsing and other specific changes that apply to my project. Check it out here: https://github.com/Nimrodda/gcm_server

  37. Hello,

    trying to use the connectionConfigurationBuilder.setSecurityMode(ConnectionConfiguration.SecurityMode.required);

    but it doesn’t quite work,
    getting this back:

    “`
    Aug 13, 2016 6:44:33 PM org.jivesoftware.smack.AbstractXMPPConnection callConnectionClosedOnErrorListener
    WARNING: Connection closed with error
    org.jivesoftware.smack.SmackException$SecurityRequiredByClientException: SSL/TLS required by client but not supported by server
    at org.jivesoftware.smack.tcp.XMPPTCPConnection.afterFeaturesReceived(XMPPTCPConnection.java:917)
    at org.jivesoftware.smack.AbstractXMPPConnection.parseFeatures(AbstractXMPPConnection.java:1376)
    at org.jivesoftware.smack.tcp.XMPPTCPConnection.access$900(XMPPTCPConnection.java:140)
    at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.parsePackets(XMPPTCPConnection.java:1017)
    at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader.access$300(XMPPTCPConnection.java:956)
    at org.jivesoftware.smack.tcp.XMPPTCPConnection$PacketReader$1.run(XMPPTCPConnection.java:971)
    at java.lang.Thread.run(Thread.java:745)
    “`

    According to multiple places on the internet including this:
    https://community.igniterealtime.org/thread/55808

    The TLS doesn’t quite work with GCM as the STARTTLS is not supported.

    How did you manage to get past that issue?
    I am using the smack xmpp v4.1.8

  38. Hi thanks for great tutorial, but my problem is gcm server stop listening after some time. If we continuously use the server it is working fine, but if there is an idle time for suppose 10 min its stop listening. Can you please help me on this issue.

  39. I went to move this into production on a web server and changed the following two lines of code from

    config.setDebuggerEnabled(true);
    XMPPConnection.DEBUG_ENABLED = true;

    to

    config.setDebuggerEnabled(false);
    XMPPConnection.DEBUG_ENABLED = false;

    And now the server does to work. I notice the application gets terminated shortly after running the jar. I have posted it on stack overflow here as well: http://stackoverflow.com/questions/39527318/runnable-jar-only-working-when-debugging-enabled

  40. Hallo!
    Thank you for your great blog! I have a question:
    Do I need to program the XMPP server for myself or can I use an “off-the-shelf” server, i.e. Openfire in order to communicate with FCM?

    1. You must ensure that you send correctly formatted message to Google and that you are able to read those transmitted to you by Google’s backend. What technology to use is up to you.

      I doubt that OpenFire (which is targeted as a chat backend) is flexible enough for you do achieve that. But I never used OpenFire, so that’s just a guess.

  41. Kanthappan Esakkiappan

    Do you have a sample Android app to send upstream messages from an Android device to backend?

  42. Sir I cannot connect to FCM Server I got this error
    org.jivesoftware.smack.SmackException$ConnectionException: The following addresses failed

    FCMSERVER=”fcm-xmpp.googleapis.com”;
    FCMPORT=5235;

Leave a Reply

Your email address will not be published. Required fields are marked *