IMPORTANT: This guide is now deprecated; please download the new Firebase Cloud Messaging extension from the Marketplace and refer to the manual provided with it (or its online documentation) for instructions on implementing it in your project.
Please note that the Google Play Services extension referenced in this Firebase tutorial requires you to be using at least version 2.2.2 of GameMaker. Please ensure you're on a suitable IDE and runtime version before starting this tutorial, otherwise your project may fail to build, but certainly won't have working push notifications.
On mobile devices, normally only one application can be active in the foreground at any time, but many games and applications operate in a time-based or interconnected environment where events of interest to users can occur when the application is not in the foreground. In these cases, Local and Remote push notifications can allow games to notify their users when the events occur, and also permit the user to start the game from the notification.
These notifications will appear as an icon and a short message at the top of the main screen on the device, and you can use them to promote a special offer, announce updates to your game, or simply invite the user to come and play again if they haven't for a while. However, before you rush off to add these into your game, it's worth noting that many users do not like these notifications, and so you should consider making them an "opt-in/out" feature from the options within your game.
This article shows you how to set up Remote Push Notifications for your Android app using the Google Play Services extension and Firebase Cloud Messaging (FCM).
NOTE: If you want to set up local notifications then please see the article Android: Local Push Notifications.
Remote notification messages are independant of your game and are sent by the Firebase server to all the devices onto which your application has been installed. There are no functions in GameMaker to deal with remote notifications, as they must all be generated by the server and handled by Firebase. 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 for a local notification.
Setup Firebase
To use remote push notifications in your game, you must first have set up Firebase from your Google Play Console. This requires you to have already created an app listing, although testing does not require you to upload an APK initially.
NOTE: If you only wish to use local notifications, you can skip this section and continue.
Once you've set up the App Listing, you need to go to the section Game Services in the Google Play console:
If your game is not listed in this section click the Add Game button and follow the on-screen instructions. Once you have added a game, select it from here and then click the Add Firebase button:
Once you have agreed to the terms that are shown, your game will be linked to Firebase. You now need to go to your Firebase Console, which can be opened by clicking the Icon beside your game name:
From here you should click the Android icon for the APP and then click the Settings button, as shown in the GIF below:
On the settings page, scroll down to the Your Apps section, and in the window where it says Download the latest config file, click the button labelled google-services.json to download this file:
You will need some information from this for the next step of the process, so save it somewhere safe. There is nothing more we need to do now in the Firebase Console, and we can move on to GameMaker.
Firebase Push Notifications Extension
Local push notifications require you to have added the Firebase Cloud Messaging extension, which you can get from the following Marketplace link
You need to add the extension to your account and then install it from your Marketplace Library (go to Marketplace > My Library in the GameMaker IDE). Once you have installed the extension, you can start to code your notifications.
NOTE: The user does not need to be logged in to Google Play and the app does not need to have the Services extension to use FCM.
With that done, you need to modify one of the configuration files within the extension itself in order to set up the Firebase app details, notification icon to use, etc... The file in question is located here:
<project folder>\extensions\GooglePushNotificationsExtension\AndroidSource\res\values\gfn_values.xml
The easiest way to find the file is simply to right click on the extension in the resource tree and then select the Open In Explorer option.
Once you've located the file, open it and fill in the values shown below with values from the following elements in the google-services.json file that you downloaded earlier:
- google_app_id: client > client_info > mobilesdk_app_id
- default_web_client_id: client > oauth_client > client_id
- firebase_database_url: project_info > firebase_url
- google_api_key: client > api_key > current_key
- project_id: project_info > project_id
You can also change the notification icons for your app by modifying the notification_icon.png files in the drawable folders in the extension Android resource folder:
<project folder>\extensions\GooglePushNotificationsExtension\AndroidSource\res
Note that Android notification icons should be saved as transparent .png files with the solid pixels representing the area of the icon that will be tinted in either the notification colour or the default system icon colours depending on the situation (this is controlled entirely by the OS). For the exact guidelines see the following article:
You can find a very useful tool for creating notification icons from the following link too:
Once you have done this we recommend that you run the project on a device to generate a client token. This will be returned in the console output and is required for testing remote push notifications from Firebase. When you run the game, you should see something like this in the output:
Copy this string to the clipboard or a text file somewhere, as you'll need it for the next step if you want to test the notifications on this device.
IMPORTANT!This key will change each time you connect a device, and you will need to retrieve and supply a new key for testing every time you disconnect and reconnect any device.
Creating A Remote Notification
Now we've set up GameMaker and have our game registering with Firebase, we can send out notifications. Firebase makes the creation of notifications very simple and it's all done through their console. To get started, got to the Firebase Console for your game and in the left hand menu, select Cloud Messaging from the Grow section, then click the "Send your first message" button:
This will then take you to the setup page for your first remote notification, and you can add in here a Title, a Label and a message to be shown to the user:
You can now click the "Test" button to send a test notification to the device you previously used to run the game on. This will open another window where you need to post your client token (the string we copied previously from the GameMaker output) and then click the (+) sign to add it to the list of test devices:
Once you have added the device, the "Test" button should be highlighted and pressing it will push the notification to your device. This may not be immediate the first time you try it, and it can take a few minutes, but subsequent tests should be almost instantaneous.
After testing in this way you can then continue and supply the rest of the required information:
- Target - Here you can target specific apps that you have live on Google Play.
- Scheduling - Here you can set when the notification is to be sent, permitting you to set timed notification or repeating notifications.
- Conversion Events - This is only valid if you have set up conversion events from the Firebase console (available from Analytics > Conversions in the left side menu in the console).
- Additional Options - Here there are a number of extra options for your notifications, and you can add data to all of them except the "Android Notification Channel" setting, as the extension will use the Default channel. If you wish to supply additional data, then you should add an "ntf_data" key and then supply a string as the value with all the payload data (this can be anything, like JSON for example). This string will be retrieved from the "data" key in the Async Push Notification event async_load DS map (see below for more details).
When finished, you can save the notification as a draft, or you can choose to review and publish it. Publishing the notification sets it live on the Firebase server and it will be sent at the scheduled time. Note that once a published notification has been sent, it can no longer be edited.
The Asynchronous Push Event
The Push Notification Event is one that is triggered by the call back from push notifications on the device OS, either from a local source using the function push_local_notification(), or from a remote source (ie: your server).
This event will be triggered immediately when a remote notification is received on the device while your app is in the foreground. If the app is in the background, then the notification will be shown on the device and clicking on it will take the user back to your app. When that happens, the async event will get triggered on launch. Also note that the event will be triggered whenever the user's Firebase client token is refreshed or retrieved from the server.
This event generates a DS map that is exclusive to the 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 (0) has been returned, then you will also have the following key:
- "error": Contains details of the error received.
If the "status" value is 1 (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 FCM registration token. For this tutorial, you don't need this token value, but for more complex server operations you may require it.
- "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"
{
// This is not required for Android, but is included should you be creating cross-platform games
var reg_id = ds_map_find_value(async_load, "reg_id");
// post reg_id to your server here
}
else
{
var data = ds_map_find_value(async_load, "data");
if ds_exists(data, ds_type_map)
{
global.push_data = data;
}
}
}
It is worth noting note that there is no guarantee that remote push notifications will be delivered. Also note that if multiple notifications are received, they will be queued for up to a maximum of 4 weeks (this can be changed in the Additional Options section when setting up the notification), and all queued notifications will be dealt with when the app is next opened.