Firebase Cloud Messaging (FCM)
Follow this procedure to implement push notification with FCM.
Introduction to FCM push notification
The push notification solution described in this section is based on the Firebase Cloud Messaging service. Familiarize yourself with FCM by visiting the Firebase Cloud Messaging web site.
Firebase Cloud Messaging services allow push servers to send notification message data to registered Androidâ„¢ or iOS devices.
- The Firebase Cloud Messaging service (FCM):
FCM provides push server and client identification. It also handles all aspects of queuing of messages and delivery to the target application running on registered devices.
- The registration tokens maintainer:
A Web services server program maintaining the database of registration tokens with application user information. This program must listen to new device registration events and store them in a database. The push server program can then query this database to build the list of registration tokens to identify the devices to be notified.
- The push server program:
Implemented by a third-party service or as a Genero BDL program using the Web services API. This push server program will send notification messages to FCM with two connection servers (HTTP and XMPP).
- Devices running the Genero app registered to the push notification
server:
Registered devices use the push notification client API to register, get notifications data and unregister from the service.
Creating a FCM project
- The google-services.json configuration file, to be bundled with your app.
- The "Server Key" is the authentication key to access Google services.
- Go to the FCM console and login with your Google developer account.
- Add a new FCM project.
- Add an (Android) app to your FCM project: Specify the same package name specified when building
your app with the
--build-app-package-name
option of gmabuildtool. - Download the google-services.json configuration file. This file needs to be added to the appdir, beside other program files.
- Skip other FCM project creation steps.
- In the project overview page, go to the settings of the new created project.
- Select the "Cloud Messaging" panel.
- Copy the "Server Key" and save it to a file. This is the key to be send with the
"Authorization:key=server-key"
HTTP header when posting a message to the FCM server endpointfcm.googleapis.com/fcm/send
.
For more details about FCM project creation, visit the Firebase Cloud Messaging web site.
Implementing the registration tokens maintainer
To handle device registrations on the server side of your application, the same code base can be used for FCM and other token-based frameworks.
For more details, see Implementing a token maintainer.
Implementing the push server
The push server will produce application notification messages that will be transmitted to the FCM service. The FCM service will then spread them to all mobile devices registered to the service with the Sender ID.
The push server will use RESTFul HTTP POST requests to send notifications through the FCM service to the following URL:
"https://fcm.googleapis.com/fcm/send"
.
Content-Type:application/json
Authorization:key=server-key
where server-key is the Server Key obtained from the FCM project settings.
IMPORT com
IMPORT util
FUNCTION fcm_send_notif_http(server_key, notif_obj)
DEFINE server_key STRING,
notif_obj util.JSONObject
DEFINE req com.HTTPRequest,
resp com.HTTPResponse,
req_msg, res STRING
TRY
LET req = com.HTTPRequest.Create("https://fcm.googleapis.com/fcm/send")
CALL req.setHeader("Content-Type", "application/json")
CALL req.setHeader("Authorization", SFMT("key=%1", server_key))
CALL req.setMethod("POST")
LET req_msg = notif_obj.toString()
IF req_msg.getLength() > 4096 THEN
LET res = "ERROR : GCM message cannot exceed 4 kilobytes"
RETURN res
END IF
CALL req.doTextRequest(req_msg)
LET resp = req.getResponse()
IF resp.getStatusCode() != 200 THEN
LET res = SFMT("HTTP Error (%1) %2",
resp.getStatusCode(),
resp.getStatusDescription())
ELSE
LET res = "Push notification sent!"
END IF
CATCH
LET res = SFMT("ERROR : %1 (%2)", STATUS, SQLCA.SQLERRM)
END TRY
RETURN res
END FUNCTION
{
"collapse_key": "stock_update",
"time_to_live": 108,
"delay_while_idle": true,
"data":
{
"stock_change":
{
"stock_id" : "STK-034" ,
"timestamp" : "2015-02-24 15:10:34.18345",
"item_count" : 15023
},
},
"registration_ids" : [ "APA91b...", "Hun4MxP...", "5ego..." ]
}
registration_ids
" attribute
to provide a list of devices to be notified. If you want to notify a single device,
use the "to
" attribute instead of
"registration_ids
", and pass a single registration token
instead of a JSON array.For more details about the JSON request structure in a FCM HTTP POST, visit the Firebase Cloud Messaging web site.
"data"
member of the JSON request defines a
"genero_notification"
member, the front-end will show graphical notification
(pop-up hint) with the "title"
, "content"
and the
"icon"
values....
"data":
{
"genero_notification":
{
"title": "Stock has changed",
"content": "New stock information will be retrieved from the backend server...",
"icon": "stock_update"
},
...
},
"registration_ids" : [ "APA91b...", "Hun4MxP...", "5ego..." ]
}
fcm_send_notif_http()
function described above. The only purpose
of this notification message is to test the "genero_notification"
pop-up hint. The
function takes an array of registration tokens as a parameter, which will be used to set the
"registration_ids
"
attribute:FUNCTION fcm_simple_popup_notif(reg_ids, notif_obj, popup_msg, user_data)
DEFINE reg_ids DYNAMIC ARRAY OF STRING,
notif_obj util.JSONObject,
popup_msg, user_data STRING
DEFINE data_obj, popup_obj util.JSONObject
CALL notif_obj.put("registration_ids", reg_ids)
LET data_obj = util.JSONObject.create()
LET popup_obj = util.JSONObject.create()
CALL popup_obj.put("title", "Push demo")
CALL popup_obj.put("content", popup_msg)
CALL popup_obj.put("icon", "genero")
CALL data_obj.put("genero_notification", popup_obj)
CALL data_obj.put("other_info", user_data)
CALL notif_obj.put("data", data_obj)
END FUNCTION
fcm_simple_popup_notif()
and
fcm_send_notif_http()
functions can then be used as
follows:IMPORT com
IMPORT util
MAIN
CONSTANT server_key = "xyz..."
DEFINE reg_ids DYNAMIC ARRAY OF STRING,
notif_obj util.JSONObject
LET reg_ids[1] = "APA91bHun..."
LET reg_ids[2] = "B4AA2q7xa..."
LET notif_obj = util.JSONObject.create()
CALL fcm_simple_popup_notif(reg_ids, notif_obj, "This is my message!")
CALL fcm_send_notif_http(server_key, notif_obj)
END MAIN
FUNCTION fcm_collect_tokens(reg_ids)
DEFINE reg_ids DYNAMIC ARRAY OF STRING
DEFINE rec RECORD
id INTEGER,
notification_type VARCHAR(10),
registration_token VARCHAR(250),
badge_number INTEGER,
app_user VARCHAR(50),
reg_date DATETIME YEAR TO FRACTION(3)
END RECORD
DECLARE c1 CURSOR FOR
SELECT * FROM tokens
WHERE notification_type = "FCM"
CALL reg_ids.clear()
FOREACH c1 INTO rec.*
CALL reg_ids.appendElement()
LET reg_ids[reg_ids.getLength()] = rec.registration_token
END FOREACH
END FUNCTION
FUNCTION fcm_send_text(server_key, msg_title, user_data)
DEFINE server_key, msg_title, user_data STRING
DEFINE reg_ids DYNAMIC ARRAY OF STRING,
notif_obj util.JSONObject,
info_msg STRING
CALL fcm_collect_tokens(reg_ids)
IF reg_ids.getLength() == 0 THEN
RETURN "No registered devices..."
END IF
LET notif_obj = util.JSONObject.create()
CALL fcm_simple_popup_notif(reg_ids, notif_obj, msg_title, user_data)
LET info_msg = fcm_send_notif_http(server_key, notif_obj)
RETURN info_msg
END FUNCTION
Handle push notifications in mobile apps
To handle push notifications in mobile apps, the same code base can be used for FCM and other token-based frameworks.
For more details see Handling notifications in the mobile app.