This article is an overview of how to set up Remote Push Notifications for your games on the Android target platform, and is for those users with experience using GameMaker, as well as experience with web servers and API procedures (if you only need Local Push Notifications, see this).
NOTE: The Firebase extension can be used to easily implement push notifications on Android & iOS. Refer to its documentation.
The method shown in this article is still applicable.
Note that push notifications are also available for other target platforms, but each one requires it's own unique setup. You can find details for the other available platforms from the links below:
Getting Started
On the Android platform, we use GCM (Google Cloud Messaging) to transmit our notifications to our games. To use this, you must first set up a Google API Project for your game, as you will need a unique project number for GameMaker, and that can only be gotten from this service.
To set this up you must first go to the Google API Console and create a new Project for your game. With that done, you will be taken to the Project Dashboard, where you will see a Project Number at the top of the screen.
The project number is the “GCM Sender ID” which you must now enter in Global Game Settings (in the Extras/Android tab).
NOTE: If you are using the legacy dashboard, this number is found from the URL in your browser. Take note of the value after#project:
as this is your project number.
Server Implementation
The server side of things is extensively documented by Google here: http://developer.android.com/google/gcm/server.html Therefore we shall not cover that part of things here. However there are some details that are important to know for the data being sent to your game from your server.
To display a push notification correctly on an Android game when a remote message is received, the following fields should be included in the data sent from your server:
“ntf_title” : This is the title of the notification
“ntf_message” : This is the text body of the notification
You do not have to include these in your notification, as it will still be pushed to your game without them, and your game will still register that they have been received, but no notification will be shown to the user. This means that the payload data you send can still be processed, but the user will not know anything (for information on how to deal with the payload data and callback events in GameMaker, see the section below).
As mentioned above, when a notification is received by GameMaker, and the game is run, it will generate an Asynchronous Event (further details are given below) where the “data” key of the generated ds_map will be in the form of a JSON string.
NOTE: It is possible to test without using a server, by doing an http post to the GCM service.
For development of your game, you can use your PC as the server but for production use, you need at least something like a VPS (Virtual Private Server), as a cheap shared hosting account is just not good enough. You need to be able to run a background process on the server, install an SSL certificate, and be able to make outgoing TLS connections on certain ports.
Example
The following is an example JSON http post that was made (for testing) using the PostMan Google Chrome extension:
POST /gcm/send HTTP/1.1
Host: android.googleapis.com
Authorization: key=AIzaSyDsKVSQzmngWVpIbrKNnUU2ixiEoTaYyWc
Content-Type: application/json
Cache-Control: no-cache
{ "data": { "score": "1000", "time": "15:10", "ntf_message": "It's Haggis Time!", "ntf_title": "nested data4", "veg": { "tasty": "false", "healthy": "true", "vegids" : [ "56","23","48" ] }, "things":[ "one","two" ] }, "registration_ids": [ "APA91bHYpzRzIs1xZl7xd3auozL-rSCe3E0RrMj1hCSQ3ehpcx5UGu077Az0FjS_w" ] }
GameMaker
There are no functions in GameMaker to directly deal with remote notifications, as they must all be generated by your server and handled by the respective Service Providers. However, once set up correctly, GameMaker games will receive these notifications, which can then be dealt with in the Asynchronous Push Event, as you would a local notification.
For all available platforms (once you have done the necessary set-up) when the game is run on a device it will register that device with the platforms push notification service. This will trigger an Asynchronous Push Notification Event, and the ds_map key "type" will have the value "register" as well as a new key, "reg_id", containing the registration id for the user device.
You must then send this registration id to your server. Your server must maintain a list of ids for registered devices, as when when you send a push notification message from your server, you use these stored registration ids to send the message to the individual devices (every device that your game is installed on will have a unique registration id).
NOTE: There is no guarantee that remote push notifications will be delivered, and that the allowed data payload for each notification is fairly small.
The Asynchronous Push Event
The Push Notification Event is one that is triggered by the call back from push notifications. It generates a ds_map (more commonly known as a "dictionary") that is exclusive to this event and is stored in the special variable async_load. This ds_map has the following keys:
"type": Value can be "local" for a device local notification, "remote" for a remote notification, or "register" for remote notification registration.
"status": Value will be "1" for success or "0" for an error.
There may be additional key entries based on the "type" returned and the "status" value. For "status", if an error has been returned ("0"), then you will also have the following key:
"error": Contains details of the error received.
If the "status" value is 0 (ie: no errors) then the ds_map will contain the following additional values, depending on the value of the "type" key:
"reg_id": If the "type" received was "register", then this key will hold the device registration id for remote notifications.
"data": If the "type" received was "local" or "remote", then this key will hold the string payload that you defined when you called the notification function.
In the event itself you would handle the callback something like this:
var type = ds_map_find_value(async_load, "type");
var status = ds_map_find_value(async_load, "status");
if status == 0
{
//error of some kind
var error = ds_map_find_value(async_load, "error");
show_debug_message("error=" + string(error));
}
else
{
if type == "register"
{
var reg_id = ds_map_find_value(async_load, "reg_id");
//post reg_id to your server
}
else
{
var data = ds_map_find_value(async_load, "data");
if data == "daily_reward"
{
global.Gold += 1000;
}
}
}