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

Handling Firebase Cloud Messaging on Android and iOS

Views:
235

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:00 April 6, 2017 2:05 pm|Code tips, General tips|21 Comments

About the Author:

21 Comments

  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:

      https://github.com/DelphiWorlds/PushClient/blob/master/DW.PushClient.pas

      • 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

    Hello,

    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!!!

Leave a Reply

Show Buttons
Hide Buttons