/, General tips/Handling Firebase Cloud Messaging on Android and iOS

Handling Firebase Cloud Messaging on Android and iOS

Discover how to handle push notifications sent from Firebase Cloud Messaging (FCM) for Android and iOS

UPDATE: For anyone who has downloaded the demo prior to May 17th, 2017, there have been 2 changes: A UseSandbox property has been added to TPushClient, that determines whether the registration is for test apps, and activation of the service connection now happens in a separate thread, to account for threading changes in Tokyo.

A few months ago, I started writing some code that was aimed at being the basis for a job for a client (and may still end up that way), and because I also needed to handle push notifications in my own applications.

At first, it was going to use AWS (Amazon Web Services), via their Simple Notification Service (SNS) as a provider because it is a much lower cost solution than for example Kinvey, and other services, plus it supports a whole bunch of messaging services. As I dug deeper into how to connect with AWS and SNS, I saw it becoming fairly complicated, and as I was doing research about it, I stumbled across the fact that Firebase Cloud Messaging (FCM) (which used to be called Google Cloud Messaging), could handle both Android and iOS.

I started working on a solution, however it was pushed down my list of to-do’s, until I came across Jordi Corbilla’s excellent article on how to receive push notifications in Android. As I wanted to also handle receiving them on iOS, I started looking into how to achieve it. I wrote some code to do the process of registering an iOS device token and receive the FCM token back, however again it was shelved due to working on other tasks.

A post from Steven Chesser in the Embarcadero forums prompted me to take another look at it, and I finally came up with a standalone solution that works for both Android and iOS. I had always planned to make this part of the code public, so the code including a demo is at the PushClient project on Github. The demo and code was built with Delphi 10.2 Tokyo, however it should also work with XE8 and 10.1 Seattle.

Here’s a brief overview of how it works:

  • TPushClient (in the DW.PushClient unit) is responsible for creating an instance of the appropriate TPushService for the platform (either Android or iOS), and the TServiceConnection, which receives the messages.
  • When the device token becomes available,  if the platform is iOS, an instance of TRegisterFCM is created, and a request to register the iOS device token is sent asynchronously to FCM. When the FCM token comes back, the OnChange event of the TPushClient is fired, and you know you now have a valid FCM token.

You can send the FCM token to your back end (if you have one) so that you can target specific devices, however you don’t need to do keep track of them if you’re just interested in sending a message to all devices that have your app installed.

You can use the FCM console to send test messages, however you may want to have a “back end” service that does this, especially if you want to target specific devices or groups of devices. I’ll cover this in a later article.

Please read the above mentioned article from Jordi Corbilla about how to set up Firebase Cloud Messaging for your application.

By |2017-05-21T08:19:50+00:00April 6, 2017 2:05 pm|Code tips, General tips|32 Comments

About the Author:


  1. Rian April 19, 2017 at 11:59 am - Reply

    I have tried the demo with delphi seattle, it’s run and installed at my android, but the deviceID is blank and the push message is failed sent from fcm. hope you can explain whats is wrong.. thank u

    • admin April 19, 2017 at 3:52 pm - Reply

      It’s more than likely you need to update the value for “package” in the Version Info of your project options, to match the package name you have in Firebase for your app. I need to update the article to reflect this, as I fell into the same trap 🙂

  2. Rian April 22, 2017 at 10:58 am - Reply

    ups, sorry i forgot to change the package name,, :), now it’s work, but the message was received if the app running. and the deviceID is still missing.. should we have to input some code into android manifest xml to wake up the appl ?

    • admin April 22, 2017 at 11:14 am - Reply

      I’m looking into both of these issues, i.e. the DeviceID, and receiving notifications when the app is not running, and plan to publish a follow-up article that addresses them.

  3. Rian April 23, 2017 at 9:15 pm - Reply

    ok thanks a lot sir.. very intresting for me to learn about fcm with delphi.. can i ask you one more question, how can i parsing the received fcm message, for example : edit1.text := gcm.notification.title; edit2.text:=gcm.notification.message;

    • admin April 23, 2017 at 9:16 pm - Reply

      I plan to cover that, too.

  4. Rian April 23, 2017 at 10:24 pm - Reply

    ok, i’ll wait your next great article. thanks

  5. Robert May 16, 2017 at 3:32 am - Reply

    I have been using same method for getting DeviceToken on Android and iOS with Berlin. But, now with Tokyo I don’t get any DeviceToken on Android devices. Any idea why? When I run the code in Berlin it still works.

  6. Robert May 16, 2017 at 6:07 am - Reply

    It crashes in line 109 of FMX.PushNotification.Android.pas where it says:
    LToken := LGCM.Register(LSenderIds);

    EJNIException: ‘java.io.IOException: MAIN_THREAD’

    • admin May 16, 2017 at 6:07 am - Reply

      I’ll take a look into it in the next day or so.

    • admin May 16, 2017 at 6:58 am - Reply

      I’ve checked in a change to the DW.PushClient unit that should work in both Tokyo and Berlin (tested here OK).

      It appears the problem is due to threading changes in Tokyo.

      A direct link to the changed unit is here:


      • Robert May 16, 2017 at 8:40 am - Reply

        Wow, that was quick! And it works, now! Thank you!

  7. Robert May 18, 2017 at 1:24 am - Reply

    Would be good to explicitly mention somewhere that one can not use the code from GitHub right away as-is, because in line 172 of DW.PushClient.pas you have coded the Sandbox parameter to True:

    FRegisterFCM.RegisterAPNToken(FBundleID, FServerKey, LDeviceToken, True)

    And I was wondering why I always get a InvalidRegistrationToken from FCM when trying to push a message for the Token I correctly received during registration… 🙂

    • admin May 18, 2017 at 6:25 am - Reply

      Thanks for the heads up! I’ll update the article..

  8. Thiago Redigulo May 21, 2017 at 7:55 am - Reply


    Congratulations by example, very good.

    But I tested on Android and worked perfectly but in IOS does not return the Token and no error, do you have any idea what can be?

    Thank you

  9. Thiago Redigulo May 21, 2017 at 8:39 am - Reply

    Thanks for the quick return.

    I have adapted your example in my APP the part of certificates and provisioning is already right and the APN key is already registered in Firebase but for some reason can not connect to return the Token.

    Image of my firebase screen: http://englishconversation.com.br/firebase.png

    • admin May 21, 2017 at 8:44 am - Reply

      Do you have the correct provisioning profile selected in your Delphi project options? That’s the only other thing I can think of.

  10. Thiago Redigulo May 21, 2017 at 9:00 am - Reply

    I have yes, but I’ll do a new test project from the beginning with your example. Then I put the result here.

    Thank you very much for your attention.

  11. Jordi Grifoll June 1, 2017 at 10:14 am - Reply

    Great and Amazing Job…. Thank you so much!!!

  12. Kardelly August 12, 2017 at 5:41 am - Reply

    In android this is ok
    In the ios the token appears, when sending a message does not arrive in ios, the send says ok for the 2 messages, it does not arrive in ios, I created the certificates, provider, key fcm ect …

    • Dave August 12, 2017 at 8:39 am - Reply

      How are you sending the message? (i.e. via Firebase console, or via HURL, as I described in the article, or by some other method) Is it received when the app is running?

  13. Kardelly August 15, 2017 at 3:17 am - Reply

    And I’m sending it through the console firebird and delphi, both say success, but the message does not arrive!
    Closed or open does not arrive that only happens in ios.

  14. Sherlyn September 28, 2017 at 8:55 pm - Reply

    I have tried this project on Android, it work well and able to receive notification. However it doesn’t work on IOS, any idea or setting i should do in firebase console?

    • Dave September 28, 2017 at 9:48 pm - Reply

      Messages sent from Firebase console will not work on iOS when the app is in the background or not running. Please use HURL (or similar) as described in the article, and ensure that a “Notification” type message is sent, not “Data”

  15. GOR November 29, 2017 at 11:24 am - Reply

    I’ve tried running a service in delphi to stay in the background but it does not work. Example: if I put it in the form and not in a service it works normally, however I want it to run as a service because I have to process the push messages in the background! Any solution for running a service?

    • Delphi Worlds November 29, 2017 at 11:37 am - Reply

      It’s not possible to use the methods outlined in this particular article inside of a service because of an issue with FMX units (which the built-in notifications system uses) and services. I may be possible however, using the methods outlined in this article:


      I plan to revisit it to investigate whether it would be possible.

  16. GOR November 29, 2017 at 11:51 am - Reply

    Thank you! It will be very interesting, due to the fact that when the application dies I can not process the push notifications, so if I were running a service it would solve the problem

  17. kang January 8, 2018 at 3:23 am - Reply

    i am use 10.2.2, and i am download puchclientdemo, sender id ,server key change and running android device, also firebase console make app, send fcm message but android device is not receive notificcation.

  18. Zidra February 1, 2018 at 9:58 pm - Reply

    I’m using delphi 10.2.2. I tested the PushClient on android and it works fine. On ios, the notifications doesn’t fire… I get the token and the device id without any problem.
    I’m sending request from my own application. I made tests on fcm console and i’m getting the same behavior…
    Any ideas?

    • Dave February 1, 2018 at 11:08 pm - Reply

      I’ve been attempting to investigate this issue, and I’m coming up against problems myself with iOS. Make sure that the Sandbox property (in TForm1.Create) is set to False, and that you have APNs set up correctly for your app in Firebase Console. Even after I’ve made sure of all that, attempting to send a message causes an “InvalidRegistration” response, and the token changes next time the app is run 🙁

Leave a Reply

Show Buttons
Hide Buttons