The Push Notes App is a Gluon code sample. Refer to the Gluon website for a full list of Gluon code samples.

In this tutorial, we’ll explain how to modify the Notes application to support push notifications and deploy it to Android and iOS devices.

Before you start, make sure to check the list of prerequisites for each platform, and you have installed the Gluon plugin for your IDE.

Note: This tutorial will use the plugin for NetBeans, but it works as well on IntelliJ and Eclipse.

Code: The code for this project can be found in the samples repository at GitHub. The sample is located under the directory pushnotes. The reader can clone this repository or create the entire project from scratch, based on the following steps.

Creating the project

This project can be created from scratch using the Gluon plugin on your favourite IDE. But since this is a follow up of the Notes app, we’ll clone the original Notes sample instead and modify it to add new features. We’ll refactor the main package to com.gluonhq.samples.pushnotes and the application class to PushNotes. Make sure to do the necessary adjustments in the FXML (fx:controller), build.gradle, AndroidManifest.xml and Default-info.plist files.

Modifying the project

Let’s start modifying the default project to create our PushNotes application, based on the Notes sample.

The model package

The model package contains the Note, Model and Settings classes, exactly the same as in the Notes sample.

The service

In the original Notes sample, we created a service that used Gluon CloudLink to persist the notes we created and/or edited locally on the device. We’ll now modify that same service by persisting the data in the cloud.

When creating the DataClient object, we’ll use OperationMode.CLOUD_FIRST to indicate that data will be directly stored into and retrieved from Gluon CloudLink. Using a DataProvider as an entry point to retrieve a GluonObservableList, we need to supply a proper ListDataReader, a valid entity with the ability to read a list of objects. For that, the DataClient instance already has one method: createListDataReader(). All it needs is an identifier (NOTES), and the object class to be read (Note.class).

You can read more about the Gluon CloudLink Data Storage service here.

Service.java
public class Service {

    private static final String NOTES = "notes-v4";

    private static final String NOTES_SETTINGS = "notes-settings-v4";

    private final ListProperty<Note> notes = new SimpleListProperty<>(FXCollections.observableArrayList());

    private final ObjectProperty<Settings> settings = new SimpleObjectProperty<>(new Settings());

    private DataClient dataClient;

    @PostConstruct
    public void postConstruct() {
        dataClient = DataClientBuilder.create()
            .operationMode(OperationMode.CLOUD_FIRST)
            .build();
    }

    public void retrieveNotes() {
        GluonObservableList<Note> gluonNotes = DataProvider.<Note>retrieveList(
                dataClient.createListDataReader(NOTES, Note.class,
                        SyncFlag.LIST_WRITE_THROUGH, SyncFlag.LIST_READ_THROUGH,
                        SyncFlag.OBJECT_WRITE_THROUGH, SyncFlag.OBJECT_READ_THROUGH));

        gluonNotes.stateProperty().addListener((obs, ov, nv) -> {
            if (ConnectState.SUCCEEDED.equals(nv)) {
                notes.set(gluonNotes);

                retrieveSettings();
            }
        });
    }

    ...

}

Registering the app

The DataClient uses a key and a secret token that are specific for the application. Those tokens are used for signing the requests that are made to Gluon CloudLink. To obtain a key and secret, you need a valid subscription to Gluon CloudLink. You can get it here (there is also a 30-day free trial). Sign up and get a valid account on Gluon CloudLink and a link to access the Gluon Dashboard.

Open the Dashboard in your browser, and sign in using the Gluon account credentials provided to create the account.

Dashboard

Go to the App Management link, and you will find a pair of key/secret tokens. Click on the download button to download the file gluoncloudlink_config.json, and then store it under your project src/main/resources/ folder.

Configuration File

The content of the file is a JSON object with the key and secret that will grant access to Gluon CloudLink:

src/main/resources/gluoncloudlink_config.json
{
  "gluonCredentials": {
    "applicationKey" : "f88XXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX",
    "applicationSecret": "7fbXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
  }
}

Running the app

After updating the project, let’s run it on desktop to test that everything is in place.

HotSpot

Before creating a native image, let’s run first the app on HotSpot with the regular JDK 11+, as this will be faster for spotting and fixing any possible issue.

Press the Run project (Notes) button or press F6, or open a terminal and run: mvn gluonfx:run.

Notes View

Create one note:

Edition View

and change the settings, we should see the results on the main view:

Main View

If we close the app and open it again, the list of notes and the settings should be the same, as everything is persisted in the cloud, thanks to the Gluon CloudLink.

Gluon Dashboard

To track all the changes that happen in the cloud application you can run the Gluon Dashboard web application in your browser. Sign in with your credentials and go to the Data Management link, you will be able to see the actual content of the settings object (Object tab) and the notes list (List tab):

Notes list

At anytime you can delete any entry, and this will be propagated to the client app.

Push Notifications

We can now add push notifications to our app in two simple steps: Adding the required Attach service and adding a PushClient instance.

Required services

First of all, let’s add the Gluon Attach Push notifications service to the pom. It will also require device and runtime-args services:

pom.xml
<dependencies>
    ...
    <dependency>
        <groupId>com.gluonhq.attach</groupId>
        <artifactId>device</artifactId>
        <version>${attach.version}</version>
    </dependency>
    <dependency>
        <groupId>com.gluonhq.attach</groupId>
        <artifactId>push-notifications</artifactId>
        <version>${attach.version}</version>
    </dependency>
    <dependency>
        <groupId>com.gluonhq.attach</groupId>
        <artifactId>runtime-args</artifactId>
        <version>${attach.version}</version>
    </dependency>
    ...
</dependencies>
...
<plugin>
    <groupId>com.gluonhq</groupId>
    ...
    <configuration>
        ...
        <target>${gluonfx.target}</target>
        <attachList>
            <list>device</list>
            <list>display</list>
            <list>lifecycle</list>
            <list>push-notifications</list>
            <list>runtime-args</list>
            ...
    ...
</plugins>

Reload the project, so the new dependencies are resolved.

Adding PushClient

On the application class, add an instance of PushClient and simply call the enable method.

PushNotes.java
public class PushNotes extends Application {

    private void postInit(Scene scene) {
        ...

        PushClient pushClient = new PushClient();
        pushClient.enable();

    }
}

Native image

Let’s test the recent changes on desktop first. Open a terminal and run: mvn gluonfx:build gluonfx:nativerun.

If everything works as it should (note there are no push notifications for desktop though), it is time to target the application for mobile platforms like Android and iOS.

These steps are already documented in the client docs for each IDE. We will refer to the NetBeans section.

Android

Firebase configuration

Follow this guide to register the app, enable Cloud messaging services, and get the google-services.json file, that should be added to the src/main/resources folder.

Note: this file is only required for Android apps. iOS apps don’t need any specific configuration for the PushClient.

Firebase config file

Deploy to Android

Connect your Android device and run mvn -Pandroid gluonfx:build gluonfx:package gluonfx:install gluonfx:nativerun, and the app will be created, installed and opened, already showing the note that was created on the desktop client:

Android App

Sending a Push Notification

Within the Gluon Dashboard web application, select the Push Notifications link and open the Configuration tab. Paste the Server Key from your Firebase Cloud Messaging application:

Server Key

Back to the Push Notifications tab you can create a new notification, pressing the + button. Provide a title, a body and an identifier and click Send.

Send notification

Immediately you will hear the notification on your Android phone.

Android notification

Clicking on it will open the application if it was closed, or put it on the foreground if it was in the background.

iOS

Certificates

Follow this step-by-step guide to get a p12 certificate for the dashboard and the provisioning profile for your app.

Signing the app

At the Apple Developer portal create and download the provisioning profile for your application.

iOS provisioning profile

Edit the pom file to configure the project to use this provisioning profile.

pom.xml
...
<plugin>
    <groupId>com.gluonhq</groupId>
    ...
    <configuration>
        ...
        <target>${gluonfx.target}</target>
        <releaseConfiguration>
            <providedSigningIdentity>Apple Development: XXXXXXX (YYYYYYYY)</providedSigningIdentity>
            <providedProvisioningProfile>Push Notes Provisioning Profile</providedProvisioningProfile>
        </releaseConfiguration>
    ...
</plugins>

Connect your iOS device and run mvn -Pios gluonfx:build gluonfx:nativerun. The app will be created and installed, and when opening for the first time, a confirmation dialog will pop up, asking if you want to allow notifications. Accept it to allow push notifications to be sent to your device for this application.

Gluon Dashboard

Create the p12 certificate and upload it to CloudLink using the Dashboard web application. Please make sure to upload the correct certificate type for the correct environment.

iOS p12 certificate

Sending a Push Notification

If you create a new notification and send it to all the devices, you should receive it in your Android and iOS devices (if both Key Server and p12 Certificate are provided).

iOS notification

Processing push notifications

When the push notification is delivered to the device, a notification shows up. When clicking on it, the application is opened if it wasn’t running, or it is resumed if it was running on the background.

You can listen to that moment, and perform some action based on the payload of the notification using the Runtime Args Service:

PushNotes.java
private void postInit(Scene scene) {
    ...
    Services.get(RuntimeArgsService.class).ifPresent(ras -> {
        ras.addListener(RuntimeArgsService.LAUNCH_PUSH_NOTIFICATION_KEY, f -> {
            System.out.println("Received a push notification with contents: " + f);
            });
        });
    ...
}

If the push notification sent from the Dashboard is marked as silent, there won’t be a visible notification, but the listener will be called and it will be able to process the payload.

Conclusion

During this tutorial we have accomplished several tasks after updating the existing Notes sample:

  • We have modified the Notes sample to add cloud persistence with DataClient and GluonObservableList. And by using the Dashboard application we’ve been able to track the changes in those persisted lists and objects.

  • We have added new services to the project: Device, Push Notifications and Runtime Args.

  • We have registered the app in Firebase Cloud Messaging and/or the Apple Developer center, and retrieved the required keys and/or certificates.

  • We have enabled push notifications on Android and iOS, and by using the Dashboard web application we have tested them on both platforms.

If you have made it this far, congratulations, we hope this sample and the documentation was helpful to you! In case you have any questions, your first stop should be the Gluon support page, where you can access the latest documentation. Gluon also recommends the community to support each other over at the Gluon StackOverflow page. Finally, Gluon offers commercial support as well, to kick start your projects.