Documentation

Did you find this helpful?

Getting Started with Android Studio and Push Notifications

Overview

This tutorial aims to help you get up and running with Android PlayFab Integration with Push Notifications. Push notifications require a configuration in several systems. Before getting our hands dirty, let's talk about how the infrastructure works. There are 4 entities participating in the process:

  • Google Play Services
  • Firebase Cloud Messaging Services (FCM, built on top of old Google Cloud Messaging) 
  • PlayFab Services
  • Client Application

Google Play Services identify your page on the play market using package name. Ex. com.bob.games.matchthree. When registered in Google Play, such package name becomes unique application ID and serves a ton of purposes from installing through Play Store to prevent impersonation.

Firebase and its Cloud Messaging Services (FCM) offer you a cloud-based system to send, direct and deliver your push notifications. It also allows other services (like PlayFab) to send push notifications on your behalf using FCM Server Key.

PlayFab Services then use FCM Server Key to send Push Notifications to your clients.

Finally, your Client Application may receive notifications and process them as needed.

As a result, we need to set up 4 different systems. This tutorial is split into 4 chapters, covering configuration for each piece. The order, in which you configure systems, matters.

Prerequisites:

  • Have a Google account
  • Have a PlayFab account
  • Generated notification icon using Generator

Scenario:

In this tutorial we will be assembling an application called "Foo PlayFab App". It is an android app that has the following functions:

  • Sign in to PlayFab using Android Device ID
  • Receive push notifications from PlayFab

Our package name will be com.foo.playfab.app. Make sure to use your own package name and title when following this tutorial

Chapter 1: Configuring Firebase

You start configuring Firebase using its official console page. You will be presented with a page where you can add a new project. Do so, by clicking area, as shown on picture below:

You will be asked provide project name. In this tutorial we use "Foo PlayFab App", but make sure to come up without your own name, when following this tutorial. Click "Create Project" to advance to the next step:

You will be redirected to the new project dashboard. Add new android application to the project by clicking on the area as shown on the picture.

New application requires 3 steps to be added. First, you have to provide Android package name. We are using com.foo.playfab.app, but please, make sure to come up without your own package name when following this tutorial. Click "Register App" to move to the next step:

Step 2 allows you to download settings file called google-services.json. It will be used later in the app to automatically configure Google services. After you download it, click "Continue" to move to the next step:

The final step offers information on how to set up your build process to wire up Firebase and Google Play SDKs. You may ignore this information, as we will be using automated tool built into the Android Studio, that does setup automatically. Click "Finish" to move to proceed:

Once application has been added, it will appear on the dashboard. At this point configuration is complete and we need to extract FCM Server Key, which we will use to wire up PlayFab Push Notifications. Navigate to project settings as shown on the picture below:

When in settings, navigate to Cloud Messaging tab and locate "Server key" item (red area on the picture below). Copy this key and store it in the notepad or somewhere else to have a quick access to it:

By this moment, we have done everything we need in Firebase to enable Push Notification.

Chapter 2: Configuring Google Play Console

When your app is ready, you will, most likely, create Google Console Project to maintain product Play Store page. Let's go though the process of creating GooglePlay project and linking it to the Firebase project. Start by visiting Google Play Console page and creating new project as shown on the picture below:

Assign the title. In this example we use "Foo PlayFab App" but, please, make sure to come up without your own title and package name while following this tutorial. Click "Create" to continue, as shown on the picture below:

Google Play Console project page will open. Locate and select "Services & APIs" on the side navigation panel, as shown on the picture below:

Services configuration page will open. Locate "Firebase Cloud Messages" panel and click "Link a sender ID", as shown on the picture below:

To link the sender ID, you use FCM Server Key you received in the previous chapter using Firebase console. When done, click "Link", as shown on the picture below:

Ensure that displayed sender ID is matching the one from the Firebase console, as shown on the picture below:

At this point, Google Play Console project is successfully linked to the Firebase project.

Chapter 3: Configuring PlayFab Title

The purpose of this chapter is to configure PlayFab services so, that it can send Push Notification to the player on your behalf. First, you need to go to Settings -> Push Notifications -> Android Settings, as shown on the picture below:

You will be asked for the FCM Server Key. Copy the one you received though the Firebase console, as shown on the picture below:

If everything is correct, you will be presented with a page, that shows Push Notifications wired (1). One last step is making sure the title is using newest FCM architecture. Click "Upgrade Push Notifications" (2):

This concludes configuring PlayFab title.

Chapter 4: Configuring Android Studio Project

In order to utilize PlayFab JavaSDK we will need PlayFab Client JavaSDK and it's dependency Google GSON:

You may download PlayFab Client JavaSDK JAR library here. Look for client-sdk-*.jar and the corresponding Java Doc if you need it.

You may download latest Google GSON here. Look for gson-*.jar

Have the aforementioned jar files nearby and start by creating regular Android Studio project and ensure package name matches the one you used throughout this tutorial (in Firebase, for instance). In this example we are using com.foo.playfab.app, but, please, make sure to come up with your own package name and title while following this tutorial:

Select minimum SDKs to you taste and click "Next", as shown on the picture below:

This tutorial suggest "Empty Activity" template to begin with. Select template you want and click "Next" as shown on the picture below:

Finally, configure the template to your needs and click "Finish" as shown on the picture below:

Once you open the newly created project, switch to "Project" tab (1). In the previous chapter you have downloaded "google-services.json" configuration file from the Firebase console. Ensure this file is places under "app" folder (2). Then, navigate to Tools (3) and select "Firebase" (4), as shown on the picture below:

The Firebase Assistant will open on the right side of the window. Locate the Cloud Messaging folder, and select "Set up Firebase Cloud Messaging", as shown below:

In the Firebase Notifications Assistant, select the "Add FCM to your app (1)" button as shown in the following image. A dialog will open indicating that new dependencies will be added via Gradle. Select "Accept Changes (2)" to grant the changes. Unfortunately, the "dependencies that are added automatically by the Gradle sync process (3)" are incorrect and will report failure! To set up the dependencies correctly, replace the auto-added sentences with the following:

implementation 'com.google.firebase:firebase-core:16.0.3
implementation 'com.google.firebase:firebase-messaging:17.0.0

Once the process finishes, ensure that Firebase Notifications Assistant indicates dependencies are set up correctly (1). In the beginning of this chapter, we have acquired necessary JAR files. Normally, gradle build file automatically fetches Ensure those JAR files are under "app/libs" folder (2). Select all of those, right click on the selection and choose "Add as library..." (3), as shown on the picture below:

Using the generator, prepare the icons and place them inside app/src/main/res. On the picture below, the icon is called "ic_stat_blur_on":

Finally, Rebuild your project, as shown on the picture below:

At this point, we can start implementing code for receiving and handling notifications. We are going to modify (and create if needed) 4 files:

  • app/src/main/AndroidManifest.xml
  • app/src/main/java/..packagePath../MainActivity.java
  • app/src/main/java/..packagePath../FooAppFirebaseInstanceIdService.java
  • app/src/main/java/..packagePath../FooAppFirebaseMessagingService.java

Please, note that current implementation is crafted to be as short as possible just to quickly test the notifications. Consider FCM Guides for high-quality best practices and implementation examples.

AndroidManifest.xml

In the following code replace MY_PACKAGE_IDENTIFIER placeholders with your own package identifier.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="MY_PACKAGE_IDENTIFIER">
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- The following block enables our custom Firebase Instance ID Service-->
        <service android:name=".FooAppFirebaseInstanceIdService" android:exported="true">
            <intent-filter>
                <action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
            </intent-filter>
        </service>

        <service
            android:name=".FooAppFirebaseMessagingService" android:exported="true">
            <intent-filter>
                <action android:name="com.google.firebase.MESSAGING_EVENT"/>
            </intent-filter>
        </service>

    </application>

</manifest>

MainActivity.java

The following placeholders in the code should be replaced according to your scenario:

  • PLAYFAB_TITLE_ID
    • The Id for your title you received in PlayFab Game Manager
  • PACKAGE_IDENTIFIER
    • Java package identifier that matches your setup


package PACKAGE_IDENTIFIER;

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import com.playfab.PlayFabClientAPI;
import com.playfab.PlayFabClientModels.*;
import com.playfab.PlayFabErrors;
import com.playfab.PlayFabSettings;
import java.util.List;
import java.util.Map;

public class MainActivity extends AppCompatActivity {

    // Invoked when activity is started
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Set PlayFab title
        PlayFabSettings.TitleId = "PLAYFAB_TITLE_ID";

        // Start login operation
        AsyncTask.execute(new Runnable() {
            @Override
            public void run() {
                if(login()) FooAppFirebaseInstanceIdService.setAllowRegisterForPush(true); // Ready to register for push notifications
            }
        });
    }

    public boolean login(){
        LoginWithAndroidDeviceIDRequest request = new LoginWithAndroidDeviceIDRequest();
        request.CreateAccount = true;
        
        // There are several approaches on getting unique android device id.
        // https://stackoverflow.com/questions/2785485/is-there-a-unique-android-device-id
        request.AndroidDeviceId = "qwerty";

        PlayFabErrors.PlayFabResult<LoginResult> response = PlayFabClientAPI.LoginWithAndroidDeviceID(request);
        if(response.Error != null){
            Log.d("Foo PlayFab App",CompileErrorsFromResult(response.Error));
            return false;
        }
        return true;
    }

    // Utility method to compose an error message out of PlayFab result.
    private static String CompileErrorsFromResult(PlayFabErrors.PlayFabError error) {
        if (error == null)
            return null;

        String errorMessage = "";
        if (error.errorMessage != null)
            errorMessage += error.errorMessage;
        if (error.errorDetails != null)
            for (Map.Entry<String, List<String>> pair : error.errorDetails.entrySet())
                for (String msg : pair.getValue())
                    errorMessage += "\n" + pair.getKey() + ": " + msg;
        return errorMessage;
    }
}

FooAppFirebaseInstanceIdService.java

The following placeholders in the code should be replaced according to your scenario:

  • PACKAGE_IDENTIFIER
    • Java package identifier that matches your setup

package PACKAGE_IDENTIFIER;

import android.text.TextUtils;
import android.util.Log;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.iid.FirebaseInstanceIdService;
import com.playfab.PlayFabClientAPI;
import com.playfab.PlayFabClientModels;
import com.playfab.PlayFabErrors;
import java.util.List;
import java.util.Map;

public class FooAppFirebaseInstanceIdService extends FirebaseInstanceIdService {

    private static String _token;

    private static boolean _allowRegistration;

    // This is invoked from activity that performs authentication.
    // Once login is complete this method is invoked.
    // If we have a pending token, we use it to register for push notifications
    public static void setAllowRegisterForPush(boolean isAllowed) {
        _allowRegistration = isAllowed;
        if (_allowRegistration && !TextUtils.isEmpty(_token)) {
            registerForPush(_token);
        }
    }

    // Invoked when firebase has fetched a token
    // If we already have logged in, we use new token to register for push
    @Override
    public void onTokenRefresh() {
        _token = FirebaseInstanceId.getInstance().getToken();
        if (_allowRegistration && !TextUtils.isEmpty(_token)) {
            registerForPush(_token);
        }
    }


    private static void registerForPush(String token) {
        PlayFabClientModels.AndroidDevicePushNotificationRegistrationRequest request = new PlayFabClientModels.AndroidDevicePushNotificationRegistrationRequest();
        request.DeviceToken = token;

        PlayFabErrors.PlayFabResult<PlayFabClientModels.AndroidDevicePushNotificationRegistrationResult> response = PlayFabClientAPI.AndroidDevicePushNotificationRegistration(request);

        if (response.Error != null) {
            Log.d("Foo PlayFab App", CompileErrorsFromResult(response.Error));
        }
    }

    // Utility method to compose an error message out of PlayFab result.
    private static String CompileErrorsFromResult(PlayFabErrors.PlayFabError error) {
        if (error == null)
            return null;

        String errorMessage = "";
        if (error.errorMessage != null)
            errorMessage += error.errorMessage;
        if (error.errorDetails != null)
            for (Map.Entry<String, List<String>> pair : error.errorDetails.entrySet())
                for (String msg : pair.getValue())
                    errorMessage += "\n" + pair.getKey() + ": " + msg;
        return errorMessage;
    }

}

FooAppFirebaseMessagingService.java

The following placeholders in the code should be replaced according to your scenario:

  • PACKAGE_IDENTIFIER
    • Java package identifier that matches your setup

package com.foo.playfab.app;

import android.util.Log;
import com.google.firebase.messaging.FirebaseMessagingService;
import com.google.firebase.messaging.RemoteMessage;

public class FooAppFirebaseMessagingService extends FirebaseMessagingService {

    @Override
    public void onMessageReceived(RemoteMessage message) {
        // Intercept the message here
        Log.d("Foo PlayFab App","Message recieved: "+message.getNotification().getBody());
    }
}

Testing

At this point you should be able to deploy the application to the device. Once you start the application, It will automatically log in and register for push notifications. Press home button on your device to minimize the application. This is important so that we can test the notification that arrives into the system tray. Next, go to your PlayFab title Game Manager page, use Dashboard to locate latest push registration and click the player id (1):

This will bring your to player page. click "Send Push Notification" button (1). Type in title (2), message body (3) and commit by clicking "Send Push Notification" (4):

Observe as the message arrives to your device:

If this is the case, messages are successfully delivered into your application. At this point you have successfully integrated. You may use FooAppFirebaseMessagingService to handle the incoming message while your application is actually running.



Did you find this helpful?