Facebook Instant Games & Firebase, store & view pending challenges

Michalis Dobekidis
4 min readJul 27, 2018
Photo by Nhu Nguyen on Unsplash

Pending requests/challenges is a great feature to have, especially for multiplayer games, however Facebook SDK doesn’t really give us many tools to go on, currently the only way to see any pending challenges is via the native Facebook menu when calling chooseAsync

And this is where this article comes into play. In order to achieve this we use a simple functionality that includes the context match-idand the opponentsuser-facebook-id

We will create two mechanics, one to receive Any challenges in any context from anyone, and one to receive pending challenges for the current context (this is especially useful for games that require subsequent actions to happen and actually the existence of this mechanic actually allows these games to be possible)

Bring all the challenges!

So the core mechanic is the following:

  • Player makes an action and make a call to the backend
  • The server (firebase functions) stores an object on a specific collection (firebase firestore-db) and inside a document named after the current context (match-id), the object contains the match-id and the pending party (opponent) that the player is waiting for.
  • When the other player of this context enters the game, they fetch the pending requests and check if any of them contain their facebook-id as a pending party. (This part can be secured even further by making an API call to the backend providing a facebook-signature for validation along with their match-id and facebook-id )
  • If any results are found and returned, possibly an indicator on the game user-interface (UI) is updated with the amount of results found (a player can be part of multiple contexts-threads)

Show us some code!

To get started we need to fetch the challenged players data (our opponent)

So after we initiate successfully the chooseAsync SDK function and we pick our opponent, we do the following:

The above code will fetch and store the connected players, but we exclude ourselves from the results, so on challengedPlayer variable we only have the data of our opponent(s).

To continue we need to send this information to the server (Firebase Functions) in order to store it (I suspect this can be done after or at the same time that we also send our play-action to the server, but the implementation can vary from game to game)

This is the function on the backend that stores the pending challenge on the Firestore-DB

Now all we have to do is check on the client-side if we have any pending request, and then do some UI work and diplay an indicator or something similar.

Here we make a query to the collection on the database (from client-side, but can be moved to backend easily). And we request to fetch all the entries that contain our facebook-id as a pending party (means other people are waiting for us to play). And then simply return those entries to a callback function.

But I want real time updates!

Yes yes I got ya covered as well.

For those of you that require real-time updates of pending-challenges, all we have to do is setup an event listener that listens for changes on that specific collection on the Database, on a specific match-id (context-id per thread). This is done on the client-side.

So each time a change happens to this match-id we fetch the data and check if our facebook-id is included on the pending-party object.

If we wish to unsubscibe from this event listener all we have to do is call callbackFn(); (The name of the returned variable of the onSnapshot call)

We added but did we delete?

One very important aspect of this mechanism is the ability to remove a pending challenge when both players have played their turn. This is very specific for each game but I will show you the code of how to delete a specific entry when your mechanics deem appropriate to do so (when both players have played or when some other action has occurred).

So when we deem approriate to delete a pending challenge entry, all we have to do is call deletePendingChallenge and provide it with the match-id that we want to remove.

When the callback returns successfully it is safe to add another entry with the same match-id and restart the mechanic.

Photo by Brendan Miranda on Unsplash

If you happen to use the above mechanic drop me a line below to see how it benefited you. Or if you have some insight/bug report/idea to offer.

As always Enjoy!

--

--

Michalis Dobekidis

Senior software engineer (7linternational.com) with a passion for games (playing and creating). I love the creative part of coding and things that are exciting!