Sign in
Log inSign up
Match-making with Firebase

Match-making with Firebase

Shukant Pal's photo
Shukant Pal
·Feb 10, 2019

Did you just build your board game for Android? Want to get it online? You are at the right place - let's build it together!!!

Overview

We are going to implement match-making with the Firebase Realtime Database in this article. For that, you need Firebase setup in your Android project here.

Prerequisites

  • Firebase users - here, we are assuming you were able to login your user into Firebase using any method. This is necessary to identify who to communicate with after the match-making is finished.

  • Gradle Dependencies - Add these to the dependencies block in your app module's grade file.

    implementation 'com.google.firebase:firebase-core:16.0.6'
    implementation 'com.google.firebase:firebase-auth:16.1.0'
    implementation 'com.google.firebase:firebase-database:16.0.6'
    
  • You aren't done after implementing match-making . That's cause you've only found two players that will play - but haven't implemented how their moves will propagate over the network. Check out the article on game communication.

Our model

We will use a node in the Firebase database called the game room which will store all the active challenges that users have pushed. Each user will search for existing challenges within the game room and will accept the first one found. Otherwise, the user will upload his own challenge and wait until someone accepts the challenge.

You will be able to add more features in your match-making implementation like matching based on similar performance ratings, friends, regional-bias, etc.

How the heck are we gonna implement that?

I've divided our problem into three objects:

  • Matcher: Finds any existing matches in the game room.

  • SelfChallengeManager: Manages the challenge a user uploads if Matcher fails to find any one.

  • SelfChallengeCanceller: Cancels the match-making process if this user doesn't wanna play anymore.

In addition, we will require a "Challenge" object that has two properties - communication node reference and the challenger's user ID (get why we need to login to Firebase now?). This object will be uploaded into the game-room by SelfChallengeManager.

Writing our components first

Before writing our three components, we need to understand what a Firebase transaction is. We don't want two users accepting the same challenge at the same time - which would corrupt our database and make our precious users angry. Transactions come to the rescue by prevent concurrent operations on a node in the database (which will be the game room).

How does that relate to our components? - Our components will be modeled as transactions as inner classes in our 'FirebasePlayerMatchMaker' class.

We use two callback interfaces - OnMatchMadeCallback and internally OnFailCallback. The factory method takes a OnMatchMadeCallback which is called whenever a match is made. The OnFailCallback is invoked whenever MatchMaker fails to find a match.

Here, findMatch runs on a separate thread and creates an OnFailCallback if Matcher doesn't find a match. In that case, we have to create a SelfChallengeManager and run it as a transaction.

  1. Matcher

    Here, the doTransaction() method iterates over all the children of the game room node and searches for a Challenge that is compatible for our user. By default, isChallengeCompat returns true, but you can change that by adding additional constraints like ratings. The first compatible challenge is then stored and the challenge node is deleted (by setting the value to null) in the database. Note that by deleting the node, the other player will be notified of the acceptance.

  2. SelfChallengeManager

    Here, the doTransaction method adds a child node to the GAME_RECORDnode in our database. This is where the game moves will be communicated after the match-making. It then uploads a Challenge to the game room and adds itself as a ValueEventListener. Whenever another user accepts the request, they will delete this node and this user will get notified as we are listening.

  3. SelfChallengeCanceller

    Our code just deletes the node created in by SelfChallengeManager by iterating over all the game room and finding our challenge. BUT ITS INCOMPLETE!!! You (optionally) should add a feature where the this user automatically resigns from the game if the match was accepted already.

In the OnMatchMadeCallback you provide to FirebasePlayerMatchMaker.newInstance, you must initialize the game communication to be done in the node (by path) mGamePath.

Yo, you've done it. Now read the article on game communication to finish up.