Skip to content
Branch: master
Find file History
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
..
Failed to load latest commit information.
Demo Update RemoteConfig with README.md. Jul 30, 2019
Editor Initial commit - Add Remote Config AutoSync behaviour with custom Jul 30, 2019
Scripts Initial commit - Add Remote Config AutoSync behaviour with custom Jul 30, 2019
Demo.meta Change from full Unity project structure. Sep 4, 2018
Editor.meta Change from full Unity project structure. Sep 4, 2018
README.md Add mechahamster details to README.md Jul 15, 2019
README.md.meta Change from full Unity project structure. Sep 4, 2018
Scripts.meta
firebase-db-auth-rules.txt Change from full Unity project structure. Sep 4, 2018
firebase-db-auth-rules.txt.meta Change from full Unity project structure. Sep 4, 2018
firebase-db-rules.txt Change from full Unity project structure. Sep 4, 2018
firebase-db-rules.txt.meta Change from full Unity project structure. Sep 4, 2018

README.md

Cross Platform Leaderboard using Firebase Database

Copyright (c) 2018 Google Inc. All rights reserved.

This solution makes it easy to incorporate a cross-platform leaderboard into your Unity® projects. You can follow the steps here to add a LeaderboardController to your own project, or take a look at the Demo Scene to see one in action right away!

Contents

  1. Requirements
  2. Setup
    1. Optional: Setup editor restricted access
  3. [Overview of Scripts](#Overview of Scripts)
  4. Usage
    1. Setting up the LeaderboardController
    2. Using LeaderboardController EventHandlers
    3. Retrieving scores
    4. Adding a new user score
  5. What's Next
    1. Security and Authorization
    2. Data Validation

Requirements

  • A Unity® project with at least full .NET 2.0 Api level enabled. To enable .NET 2.0, go to Edit -> Project Settings -> Player -> Other Settings and change Api Compatibility Level to `.NET 2.0.
  • A Firebase project. You can create a new Firebase project using the firebase console.

Setup

  • Follow the Setup steps for using Firebase Database with Unity®.
  • Set up public access to your database. Note that this leaves your database open to the public, so you will want to configure rules before releasing your game.

Optional: Setup editor restricted access

If you choose to use rules that disallow public access, you will need to configure the SDK to use a service account to run in the Unity® Editor.

  • Copy the rule text found in firebase-db-rules.txt.
  • Go to the firebase console, select your project, choose Database and click on the Rules tab. Paste the contents of firebase-db-rules.txt.

Overview of Scripts

To understand how you might customize these scripts for use in your project, start by exploring each script implemented in the Firebase_Leaderboard>Scripts directory, Firebase_Leaderboard>Demo and Mechahamster. Feel free to read through the code in Unity as you orient yourself to these scripts.

If you update the LeaderBoardController script for your game, you will need to update this script with any new information.
Script Name Script Purpose
Assets>firebase-unity-solutions>Firebase_Leaderboard>Scripts>FirebaseInitializer This is a centralized script for initializing FireBase in your project.

You should not need to modify this script to customize for your game.

Assets>firebase-unity-solutions>Firebase_Leaderboard>Scripts>LeaderboardController This script creates the Firebase.Leaderboard namespace, which is called by many of the other scripts. It contains the primary logic for the leaderboard and handles keeping the data from Firebase and Unity Game code synchronized by sending events to Firebase and triggering updates in the game when receiving new data.
Assets>firebase-unity-solutions>Firebase_Leaderboard>Scripts>TopScoreArgs Defines the event arguments which are sent when LeaderboardController invokes TopScoresUpdated.
Assets>firebase-unity-solutions>Firebase_Leaderboard>Scripts>UserScoreArgs Defines the event arguments which are sent when LeaderboardController invokes UserScoreUpdated.
Assets>firebase-unity-solutions>Firebase_Leaderboard>Scripts>UserScore Represents a single user score record kept in FirebaseDatabase. By default a user score contains a timestamp, score value, and the User's unique ID. You may modify this class to add fields, but if you remove or change any of the three default fields, you will need to update the logic in LeaderboardController to match.
Assets>firebase-unity-solutions>Firebase_Leaderboard>Editor>LeaderboardControllerEditor Creates the LeaderBoard interface, allowing the user to set certain variables and paths in the Unity Inspector window.

Assets>firebase-unity-solutions>Firebase_Leaderboard>Demo>DemoUIController In the Firebase_Leaderboard DemoScene, this script controls the Demo Interface.
Assets>Hamster>Scripts>States>UploadTime In Mechahamster, this script creates a class called UploadTime, which manages the transfer of data to Firebase when the user selects the Submit! button at the end of a maze and logs their score.
Assets>Hamster>Scripts>States>TopTimes In Mechahamster, this script creates a class called TopTime, which manages the top finish times for a level.
Assets>Hamster>Scripts>Menus>TopTimesGUI In Mechahamster, this script creates an Interface class for providing code access to the GUI elements in the high score menu.
Assets>Hamster>Scripts>States>LevelFinished In Mechahamster, this script creates a class called LevelFinished, which manages the logic driving the Level Finished menu page.
Assets>Hamster>Scripts>Menus>LevelFinishedGUI In Mechahamster, this script creates an Interface class for providing code access to the GUI elements in the Level Finished menu.

Usage

Setting up the LeaderboardController

  • If you haven't already, copy all the .cs source files from Scripts to your project.
  • Add the LeaderboardController MonoBehaviour to a GameObject in your scene.
    • It is advisable to disable the GameObject with the LeaderboardController component attached when the player is not viewing the Leaderboard, as leaving it enabled will cause the LeaderboardController to continue to listen for new score records being added to the DB.
  • Fill out the fields on the controller as appropriate.
    • EditorAuth: Enable this and fill out the following optional parameters if you have set up restricted editor authentication for your project.
      • EditorP12FileName: The location of the P12 key file downloaded when restricted access was set up.
      • EditorServiceAccountEmail: The service account that has access to your database. This can found on the cloud console's IAM control.
      • EditorP12Password: The password generated for restricted access.
    • AllScoreDataPath: If you wish to use a different path to keep all the user score data (for example, if you are already using Firebase DB for other data and want to use a longer path), you can change that here.
      • Note that if you do, you will also need to update the path in the rules text if you set up editor restricted access.

Using LeaderboardController EventHandlers

Because Firebase Database calls are asynchronous, the functions that retrieve and add data to the DB do not return their results directly. Instead, you subscribe to EventHandlers that trigger when a result is completed.

There are three events that fire when the LeaderboardController completes various actions.

  • ScoreAdded: Called when a new user score is saved to the DB.
  • UserScoreUpdated: Called when the current user's top score is retrieved.
  • TopScoresUpdated: Called when a set of all users' top scores is retrieved.

Retrieving scores

Top Scores

Retrieving top scores is as simple as specifying the NumScoresToRetrieve, EndTime, and Interval fields on the LeaderboardController. When the component is enabled, and Firebase is initialized, it will automatically retrieve the top scores from the requested time frame. If EndTime is the present (0), it will also listen for any new scores that would displace any of the current top scores, and send TopScoresUpdated events accordingly.

For example, if you retrieved the top 5 scores, and the score values are 15, 20, 22, 24, and 31, then the LeaderboardController sends 1 TopScoresUpdated event with those scores when it is enabled. Then, if a new score that is > 15 is added while the component is enabled, it will send a new TopScoresUpdated event with the updated list.

User Scores

If you want to retrieve the top score for a particular user, call GetUserScore and provide the user's unique ID. When the asynchronous call is complete, the UserScoreUpdated event is invoked.

Adding a new user score

To add a new user score, simply call AddScore with the following fields:

  • userId: The unique ID of the user for whom to add a score, based on whatever authentication method (Firebase Auth or otherwise) you prefer.
  • score: The new score (as an integer).
  • timestamp (default now): The time the score was achieved.

What's Next

Security and Authorization

The rules provided in firebase-db-rules.txt are pretty limited, and don't offer any validation that user's are not manipulating other scores in all_scores data. A malicious user could potentially fake their own high score, or even delete other user's scores!

With some build platforms, this may not be a danger, as the code to find the database URL may be obfuscated or hidden. However, you will likely want to protect this data with more limited write rules, limiting what data a user can manipulate via authentication.

The easiest way to do this is to incorporate Firebase Authentication, as Firebase Database has the built-in auth variable that contains a user's uid. If you do use Firebase Authentication, you can replace the rules text for your database with the text in firebase-db-auth-rules.txt. This limits new score data writes to entries whose user_id attribute matches the auth.uid. Remember that you must pass the Firebase Auth UID to the AddScore as the user's ID, or the writes will fail!

Data Validation

Using Firebase Auth to restrict write access to user's own records will prevent users from being deleting or manipulating other users' records, but it won't stop a malicious user from manipulating their own score data. Again, the likelihood of this happening depends on the build platform.

One common method of securing against this vulnerability is to obfuscate the score in some way, upload the obfuscated value to the Firebase Database, and then have a server-side or serverless process that you control read and respond to that data to calculate the score.

This could be as simple as hashing the score value and de-hashing via a Cloud Function, which then updates the Firebase DB score value for the user.

Or, instead of uploading the score value to the DB, you could instead upload some data about the final game state, and then have a server-side process read that state, compute a score from it, and update the score value in kind.

You can’t perform that action at this time.