Appsurd
Member
Push Notifications on Android
GM version: GM: Studio 1.4.1804 Professional (2018-03-18)
Target platform: Android
Download: https://marketplace.yoyogames.com/assets/4818/push-notifications-example
Links: N/A
Latest change: 2018-08-09
Level: Advanced
Summary
This tutorial will explain how you can make your own Push Notifications on Android. The tutorial will first cover the local push notifications (which means that a user gets a notification after a specific amount of time) and the remote push notifications (for example, you receiving a WhatsApp message from another user). I created an example in which you can see the code yourself. You can download it from YoyoGames’s Marketplace: https://marketplace.yoyogames.com/assets/4818/push-notifications-example
Please note that if you want to fully understand this tutorial, it is strongly advisable to read my earlier tutorial about “Online Highscores” first since we will use the same database system: https://forum.yoyogames.com/index.php?threads/online-highscores.4291/
Table of contents
Introduction
Chapter 1: Local Push Notifications
Chapter 2: Remote Push Notifications: Google Cloud Messaging
Chapter 3: Remote Push Notifications: In Altervista
Chapter 4: Remote Push Notifications: In GameMaker: Studio
Conclusion
Error solving: 401 unauthorised
Changelog
Introduction
Have you ever wanted to create an awesome app where players would be able to battle each other? After you came to the conclusion that making a real-time online app was too difficult, you started searching for a turn-based method (of which chess is the most famous example). But how could you let the other player know it is their turn to play?
In this tutorial this problem will be solved. I will try to go in-depth and tell why and how this can be done using push notifications. First we will be going through the local push notifications and secondly we will explore the remote push notifications. YoyoGames has already written a decent tutorial about this subject, so I strongly recommend you reading that first: http://www.yoyogames.com/blog/31. After reading the introductory blog post, you should know what the general idea is. Since Yoyo also wrote a decent introductory tutorial about remote push notifications on Android, I strongly suggest that you read that too so you know what I'm talking about: http://help.yoyogames.com/hc/en-us/articles/216753458-Push-Notifications-Android.
Now you’re done reading that whole lot of information, it’s time to start to go in-depth and look into the myths of push notifications.
This tutorial and all its assets are completely free, there is no need for any credit at all to Appsurd. We do appreciate if you rate the script in the Marketplace such that we know what can be improved. Thanks in advance and enjoy the tutorial!
Chapter 1: Local Push Notifications
Local Push Notifications are actually quite easy to implement. After reading YoyoGames’ tutorial, it should be clear how you should use it. Don’t forget to download Yoyo’s asset https://marketplace.yoyogames.com/assets/2008/google-play-services from the Marketplace and add it to your project. I’ll now just present you some useful functions.
The notifications are local, implying that the local push notification will be send to the player’s device only. Generally, one could use this after a user hasn’t opened your app for a while, and you want to grab his/her attention with a special offer or maybe a reminder of getting his/her daily reward.
Pushing a notification is done using the function push_local_notification(fire_time, title, message, data). An example is shown below.
Code:
var time = date_inc_second(date_current_datetime(),15);
push_local_notification(time, "My App name", "Just for testing local push notifications", "This is a test message from the local push notification.");
The second argument is the title of your message, which you would mostly want to be the title of your game or app. The third argument is the message displayed below the title, here you should place the message you want to give to the player. An example is: “Come back and claim your daily reward!”
The fourth argument is the data passed to the app. Unfortunately, it does not matter whether the player opens the app via the local push notification or the player swipes it away and opens the app in the normal way, in both scenarios the data is transmitted to the app. This makes it in my opinion quite useless, but maybe you can think of a useful application for it.
Just as I said before, the data of the notification can be received by the app. First load the player’s registration ID in the Create Event.
Code:
// Initialise register_id
ini_open("File.ini");
global.reg_id = ini_read_string("Reg","Reg","");
ini_close();
Code:
/// Handle the data of the push notification
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_message_async("Error:#" + string(error));
}
else
{
// registering for the first time (this is always called at the start of the app)
if type == "register"
{
var reg_id = ds_map_find_value(async_load, "reg_id");
// If the player's hasn't registered before, save the registration ID to the ini file
if reg_id != global.reg_id
{
global.reg_id = reg_id;
ini_open("File.ini");
ini_write_string("Reg","Reg",global.reg_id);
ini_close();
show_message_async("New register ID:#"+string(global.reg_id));
}
else
{
show_message_async("Old register ID:#"+string(global.reg_id));
}
}
else // show the data received
{
var data = ds_map_find_value(async_load, "data");
show_message_async("Data:#"+string(data));
}
}
There are three more functions available for the local push notifications.
Push_get_first_local_notification retrieves the first local notification which is coming up.
Push_get_next_local_notification can be used after the previous function and simply gives the next notification.
Push_cancel_local_notification can be used to cancel a specific notification which you had already set before.
The usefulness of these functions is covered by an example which I took directly from Yoyo’s manual as it’s just perfect to illustrate how to use them.
Code:
var map = ds_map_create();
// Find the first notification
var ntf = push_get_first_local_notification(map);
// As long as this notification exists
while(ntf >= 0)
{
// If the notification is a daily reward, remove it
var data = ds_map_find_value(map, "data");
if data == "Daily_Reward"
{
push_cancel_local_notification(ntf);
}
// Go to the next notification
ntf = push_get_next_local_notification(map);
}
ds_map_destroy(map);
Chapter 2: Remote Push Notifications: Google Cloud Messaging
Remote push notifications are almost the same as local ones, except that the developer or other players can set the notification for someone else. This ensures the possibility to create a chat and the other chatter receiving a message as a push notification, just like WhatsApp does. In order to be able to start the whole process, we should first create a project in Firebase.
Just a small side note: since September 2016 it is obligatory to use Firebase Cloud Messaging. Before that, there was another system simply called Google Cloud Messaging. Please DO NOT use the old system anymore, it might cause strange errors!
Let’s go to https://console.firebase.google.com/ and login with your Google account (preferably use the same one as you use for your apps on the Google Play Store). Of course you may create a new account for it as well. Now let’s create a new project, so press “Create new project” as shown in Figure 1.
Figure 1: The Firebase welcome screen. Click on "Add project" to create a new project.
After pressing the “Create new project” , you are prompted to give your project’s name. I will choose “Push Notifications Tutorial” in this case. I recommend you to use the name of your game as a project name. Furthermore, select your country.
Figure 2: Creating a new project. Preferably choose the project name to be the name of your game.
Now press “Create Project”. Now your project is being created. This could take a couple of seconds. After that, you are forwarded to a screen and quickly after that, you will see the overview of the project. See Figure 3.
Figure 3: The overview of the your project. We will only need one function in this tutorial, all others are not interesting for now.
Notice your project name in the top left orange frame, this should of course be the same as the project name you just entered. Until now, we created a project only so we need to get some information about the project to be able to use the push notifications. Let’s go to the “Project settings” for that (see Figure 3). You should now be seeing something like I have (see Figure 4).
Figure 4: The general settings of your project. Go to the “Cloud Messaging” tab as indicated by the orange frame.
Here you see the general section of the settings, thus some general information about your project. First of all, your project name is displayed. Thereafter, the public-facing name is shown. This is the name visible to your users, so I would recommend to leave it as it is. Below that, your project ID is displayed. We DO NOT use this ID, since we cannot use it. And last but not least, the Web API key is shown. As the name already suggests, this key is for web developing, so it is of no interest to us.
Next to the general tab, there is a tab called “Cloud Messaging” as shown in Figure 4 by the orange frame. Click on it to go to the “Cloud Messaging” section. You should now see the screen shown in Figure 5.
Figure 5: The section “Cloud Messaging” in the settings of your project. The most important codes are the sender ID and the Server key.
Here we have exactly what we need. First of all, copy the sender ID code (see Figure 5) and save it somewhere because we will need it further on in the tutorial! You will use this code for GameMaker: Studio to identity with Firebase. After that, copy the code below the Server key (see the lower orange frame in Figure 5) and save it somewhere because we will need this too! This is to make sure that your PHP script (which we will create in chapter 3 of this tutorial) is able to connect to the Cloud Messaging service.
And actually that’s it! You may close this page as we do not need it anymore in this tutorial. Do remember to save the codes I mentioned, since we definitely need those. Let’s continue the tutorial and set up a database system.
Chapter 3: Remote Push Notifications: In Altervista
Now we have set up the project correctly in the Google Firebase environment, it is time to look into the PHP side. For me, it was quite weird to find out that you could not directly communicate from GameMaker: Studio with the Google Cloud Messaging server. This makes it a little more complicated, but since Google chose for this, we will have to deal with it! On the other hand, communication with another player requires you to have his registration ID, so it’s quite logical actually! So let’s get started!
This is the part that YoyoGames’s tutorial is actually lacking information on how you should do this, especially if your knowledge about web communication is not too big. In this tutorial, we will use a free website and a database, known as Altervista. If you do not know what I’m talking about, please follow my earlier posted tutorial “Online Highscores” https://forum.yoyogames.com/index.php?threads/online-highscores.4291 first, and especially the first two chapters of that tutorial contain vital information about the registering on and working with Altervista.
From now on, I assume that you have an Altervista account and that you know how to add a table and how to add PHP files. If you do not, please recall the tutorial “Online Highscores” for more information. It’s time to move into the coding of the online part. Login to Altervista and go to your Dashboard. Then you should see something like this:
Figure 6: The Dashboard of Altervista.
First of all go to the “File Management” section as in the upper orange frame. There I will create a new map, called “PushNotifications”. Maybe your app’s file name is already there, then you can use the same map and you do not have the create a new one. Inside the map, we will create two PHP files: one for registering and one for sending the notification to the GCM server.
First create a PHP file called addpush. Open it and put the following code into it. Do not forget to change the names tutorialappsurd (account name) and my_tutorialappsurd (database name) and the 1234 (secret key) to the ones you have chosen!
Code:
<?php
// Connect to database
$db = new PDO('mysql:host=localhost;dbname=my_tutorialappsurd', 'tutorialappsurd');
// Check secret key, if correct, then insert name and score
$secretKey = "1234";
if($secretKey == $_POST['hash'])
{
// Send variables for the MySQL database class.
$sql = "INSERT INTO PushNotificationsIDs VALUES (NULL, :reg_id)";
$stmt = $db->prepare($sql);
$stmt->bindParam(':reg_id', $reg_id, PDO::PARAM_STR);
// Get reg_id from URL string
$reg_id = $_POST['reg_id'];
// Execute statement
$stmt->execute();
echo '1';
}
else
{
echo '0';
}
?>
You need to call this script only once, so only when the player opens your app for the very first time, but I will explain this in detail in chapter 4.
Now create the second script sendpush and put the following code into it.
Code:
<?php
// Connect to database
$db = new PDO('mysql:host=localhost;dbname=my_tutorialappsurd', 'tutorialappsurd');
$secretKey = "1234";
if($secretKey == $_POST['hash'])
{
// Get all data from the table
$sql = "SELECT reg_id FROM PushNotificationsIDs";
// Prepare statement
$stmt = $db->prepare($sql);
// Execute statement
$stmt->execute();
// Fetch all results and put them in an array
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row)
{
$list_reg_id[] = $row['reg_id'];
}
//print_r($list_reg_id);
// Check if the array isn't empty
if ($list_reg_id == "")
{
echo "No push ID's found";
exit();
}
// Initialize curl
$ch = curl_init();
$api_key = "AIzaSyBTAM******************";
// Enter variables (the Authorization key is the Server key from Firebase)
$header = array(
'Authorization: key=' . $api_key,
'Content-Type: application/json'
);
// Enter variables for the push notifications itself (you may change these of course)
$body = array(
'data' => array(
'ntf_title' => 'Tutorial Push Notification',
'ntf_message' => 'Just for testing remote push notifications',
),
'registration_ids' => $list_reg_id
);
// Setting some parameters, please do not change this
curl_setopt($ch, CURLOPT_URL, 'https://android.googleapis.com/gcm/send');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body));
// Execute posting to GCM
$result = curl_exec($ch);
if ($result === FALSE)
{
die("Curl failed: " . curl_error($ch));
}
// Results of post in $result
echo $result;
}
else
{
echo '0';
}
?>
Just as in the previous script, at first a connection is made with the database. After that, the secret key is compared to the one on the server. If correct, all registration IDs known by the server are gathered and put together in a list.
Then curl is initialised. This set of functions takes care of the POST request to the GCM server. You will see the so called API key in the script. Here you should put in the code from the Server key from the Firebase environment which we saved in chapter 2.
After that, the title and message of the request are entered. You may of course change these values into whatever you want. Directly after that, all parameters used by the GCM are set up. Do not change these, otherwise you might get weird errors!
Finally, the created request is posted to the GCM server. Just a final remark about this script, when you are curious to know what a certain function does, try to google it first, there are many (also non-GameMaker) examples available which explain the PHP and Curl functions in a very clear way.
This script creates an array of all users known in the database. Maybe you want to send a push notification to a specific user only. You will then need to store (and get) the registration ID of the other player and submit that to the GCM. I cannot give one a cut-and-clear answer to this, since the final construction of the database and the PHP files are different whenever you want something different. I’m afraid you will have to figure it out alone, but I assume you’re almost a professional GameMaker developer, so I’m sure you can do it.
Now it’s time to create a database. Go back to your Dashboard (see Figure 6) and click this time on the lower orange frame on “Access to PHPMyAdmin”. Now a new tab opens. Click in the left column on your my_tutorialappsurd database. You will see something comparable with the following figure.
Figure 7: Creating a new table in the PHPMyAdmin environment in Altervista.
Now enter a suitable name for your table, such as PushNotificationsIDs (preferably the name of your game + something like IDs). We will need two columns, so set the number of columns to 2. Then press “Go”.
Go to the first row under “Name” and enter the word id. Leave the Type to INT. Fill at Length/Values the value 10 and check the checkmark in the one but last column called “A_I”. This ensures that each player in the list gets its own id and that registration IDs will not be overwritten accidently.
Now continue on the second row and enter reg_id under “Name” and choose VARCHAR as “Type” and fill in the value 1000 in “Length/values”. This means that reg_id is a string with a maximal length of 1000 characters.
This is all you need, so you can save the table now. This means that we are finished in Altervista. In the next chapter, we will see how you can code in GameMaker: Studio such that you can actually use the remote push notifications in your own game!
Chapter 4: Remote Push Notifications: In GameMaker: Studio
In the previous chapter, we went through all code in Altervista, such that we only need to finish the job in GameMaker: Studio. The first thing we need to do is to go to the Global Game Settings -> Android/Fire -> Social. Here you should check the checkbox with “Enable Push Notifications”. Immediately below it, you will see “GCM Sender ID”. Here you should enter the Sender ID of the project you have created in Firebase (recall the end of chapter 2 in case you forgot).
We will now follow the same route as in chapter 1 about the local push notifications, however, it’s actually easier now. Let’s create a script called send_push_notification. Put the following code into it.
Code:
///send_push_notification()
//
// Script: Sends a remote push notification to all other users
// Date: 2018-07-28
// Copyright: Appsurd
var data = "reg_id="+string(global.reg_id)+"&hash=1234";
post = http_post_string("http://ftp.tutorialappsurd.altervista.org/PushNotifications/sendpush.php",data);
Now we need something in-game to handle the data send. We will use almost the same code as in chapter 1. Now put the following code in the Create Event of the first object in your game. Please note that this object should be persistent and always present. This ensures that it won’t miss the return from the GCM server.
Code:
/// Initialise register_id
post = -1;
ini_open("File.ini");
global.reg_id = ini_read_string("Reg","Reg","");
ini_close();
Code:
/// Handle the data of the push notification
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_message_async("Error:#" + string(error));
}
else
{
// registering for the first time (this is always called at the startup of the app)
if type == "register"
{
var reg_id = ds_map_find_value(async_load, "reg_id");
// If the player's hasn't registered before, add reg_id to the database on Altervista
if reg_id != global.reg_id
{
global.reg_id = reg_id;
ini_open("File.ini");
ini_write_string("Reg","Reg",global.reg_id);
ini_close();
var data = "reg_id="+string(global.reg_id)+"&hash=1234"; // Fill in your own hash (1234)
post = http_post_string("http://ftp.tutorialappsurd.altervista.org/PushNotifications/addpush.php",data); // Fill in your own account name (tutorialappsurd) and map name (PushNotifications) here
show_message_async("New register ID:#"+string(global.reg_id));
}
else
{
show_message_async("Old register ID:#"+string(global.reg_id));
}
}
else // show the data received
{
var data = ds_map_find_value(async_load, "data");
show_message_async("Data:#"+string(data));
}
}
We are almost done by now! The only thing we still haven’t done is adding the Google Play Services extension to the project. Open up the Marketplace and download the Google Player Services extension from https://marketplace.yoyogames.com/assets/2008/google-play-services and add it to your project.
That’s it! You are done by now and know now how you can use push notifications in your own app! Perhaps not everything is too clear yet for you, so I created an example in which all code is used which I discussed in this tutorial. You can download the project in the Marketplace: https://marketplace.yoyogames.com/assets/4818/push-notifications-example. You may copy the code to use in your own projects, but please do not sell it under your own name. Please note that you cannot compile the code given in the example since I used a different secret key. In my previous tutorial, I noticed that many users (accidently) screwed up the highscore table and I don’t want that to happen in this tutorial too, so I hope you can forgive me
Conclusion
The tutorial is finished by now, I hope you have learned how you can create your own push notifications in GameMaker: Studio. We saw that local push notifications barely cost any time, but remote push notifications required much more work but the result is very awesome. If there are any questions or if you find anything unclear, please post your response in the comments below. Thanks for reading the tutorial and have fun with your push notifications!
Error solving: 401 unauthorised
Sometimes the GCM server returns a “401 Unauthorised Error”. I am not completely aware of what is going wrong. Mostly this is due to sending the GCM a registration ID which is not known by GCM. This could happen if the player has deleted your app or something got messed up in the Altervista database which yields incorrect registration IDs. I first recommend to empty the database. Thereafter carefully check if the PHP files and your GameMaker: Studio setup is the same as described in the tutorial. Whenever you are still experiencing the problem, you may try to create a new project in Firebase. If it still doesn’t work, I’m afraid I can’t help you out and I would love to hear from you when you found a solution.
Note that if you are accidently using the old version of Google Cloud Messaging, the message “401 Unauthorised Error” will be shown every single time. So DO NOT use the old version!
Changelog
Changelog, huh? Yes, it’s actually just for me to check when and what I changed in the tutorial. Any people contributing something will be added too.
V1.0.3 (2018-08-09)
- New screenshots since Firebase looks a little different
- Small text fixes
V1.0.2 (2018-04-08)
- Removed APK as it was not used by many
- Small text fixes
V1.0.1 (2017-07-24)
- Fix: You require the Google Play Services asset for local notifications
- Fix: PHP send script only took one value instead of all
- Text fixes
V1.0.0 (2016-11-28)
First English version of the tutorial was written.
Last edited: