Friday, 27 January 2017

Firebase Cloud Messaging with Delphi 10.1 Berlin update 2.

A comprehensive step by step guide, covering everything you need to know to receive push notifications to your Android device using Firebase Cloud Messaging and the latest Delphi 10.1 Berlin update 2.

Push notifications let your application notify a user of new messages or events even when the user is not actively using the application (downstream messaging) ( On Android devices, when a device receives a push notification, the application's icon and a message appear in the status bar. When the user taps the notification, they are sent to the application. Notifications can be broadcast to all users, such as for a marketing campaign, or sent to just a subset of users, to give personalised information. To provide this functionality I will rely on Firebase Cloud Messaging which is the new version of GCM (Google cloud messaging) and Delphi to develop the Android application.

1. Create your Firebase project

Create your Firebase project by visiting the console if you still don't have one and in this project create an Android App.

I already have one project so I will use this one for my demo. Once in the project, go to Overview -> Add another app -> Android:

And give it a sensible name. In my case I called the package com.embarcadero.FirebaseCloudMessaging. This package name is important as it will be referenced later on. Once you click Add App, you will receive a google-services.json file which contain information that we will use later.

The package name is defined in your Delphi project:

So make sure that everything matches with the name you give to your Firebase application as the manifest file will contain this information.

2 Request your FCM Token

Now that we have our project configured, we need to request Firebase a unique token for our Android device. You can see the description here as to how to get the FCM token via Android Studio, but I will show the necessary steps to get the same value from our Delphi application.

Basically we are trying to get the same value from FirebaseInstanceId.getInstance().getToken(). We will achieve the same behaviour by using TPushServiceManager which is the unit responsible for handling push notifications.

The following code snippet tries to request the FCM token via TPushServiceManager:

Now, to allow this code to work correctly, we will have to configure few things.

a) Enter the Sender Id.

In the source code snippet above, I'm mentioning the SENDER ID. This sender id, can be found under Firebase -> Project Settings -> Cloud Messaging:

This is the value you have to put here:

PushService.AppProps[TPushService.TAppPropNames.GCMAppID] := 'SENDER ID';

Knowing that the GCMAppId is actually the Sender Id has been a quite a struggle for some users and you can see my answer on Stack overflow.

b) Configure the project to receive push notifications.

In the Delphi IDE, go to your project options -> Entitlement List and set the property Receive push notifications to true.

c) Configure the AndroidManifest.template.xml file.

Before we try to run the code above, we'll have to configure the manifest file to grant our device permissions to connect to Firebase. If you don't configure the permissions, you might run into an exception like the one below:

Error message: EJNIException with message 'java.lang.SecurityException: Not allowed to start service Intent { (has extras) } without permission'.

See the code snipped below for reference:

The full source code of the solution can be found here for reference where you can find the manifest files.

Once everything is configured, we can now test if we can receive the FCM token. Here is a screenshot of my project so you can see that there are two buttons, one to receive the token and the other one to store this token somewhere so the system that sends the notification knows the receiver.

Let's see the project in action here:

As you can see in the image above, I get the DeviceID and the FCM Token. The one we are interested in is the FCM Token. This token is quite large so it does not appear completely on the screen.

Now we need to configure what to do when we receive a notification and how this notification is built.

3 Receive your first FCM Push notification

The following code snipped will configure the OnReceiveNotification event and will display a notification using the TNotificationCenter class.

Notice that the ServiceNotification variable contains a DataKey member which contains a JSON envelope. This object will contain all the information of our push notification. Here you can see how this notification looks like:

Notice that the message is part of the gcm.notification.body property and this one is the one that we will use for our DataObject.GetValue method.

Let's see the application in action:

Here you can see side by side my Android device and Firebase Notification testing system. Once the application is ready to receive notifications, you just need to send the notification using the configured app or the token if you want to target a single device.

Next step is to store these tokens on the cloud and use your own system to deliver those messages.

Please, do not hesitate to contact me if you have any further questions.

Related links:

Embarcadero MVP.