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.
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.
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.
The content of the file is a JSON object with the key and secret that will grant access to Gluon CloudLink:
{
"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
.
Create one note:
and change the settings, we should see the results on the 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):
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:
<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.
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.
-
For Android: Create & install an Android native image.
-
For iOS: Create & install an iOS native image.
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.
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:
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:
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
.
Immediately you will hear the notification on your Android phone.
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.
Edit the pom file to configure the project to use this provisioning profile.
...
<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.
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:
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
andGluonObservableList
. 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.