Realtime Database

Guild Chat Unity Hook-up with Firebase Realtime Database

Benjamin Button Edition, Part 2

Osman Kaan Demiroz
Firebase Developers

--

In case you haven’t read the initial post from my teammate, Alex Harbi, on building the back-end for chat functionality in our guild-based team environment (what our House Flip players affectionately call Squads), it’s a great primer on Firebase Realtime Database and why we chose it to power this necessary feature for community collaboration. If you missed that article, feel free to check it out as well.

As my section is mainly focused on the client, I’m going to share how we used the Firebase Unity plugin to hook-up everything (plus share some nice tidbits on sound frontend design).

Client Setup

On the client side, Firebase Realtime Database works by setting up event handlers for values that are changed, added or removed within the database. This means the client can connect and listen to events directly from Firebase, without requiring an intermediate connection through our server. Of course our client actions still pass through our server, but we can listen to the updates directly from the Realtime Database.

House Flip is built on Unity, and so we made use of the Firebase Unity plugin which includes the Realtime Database package. The SDK comes with many accessors and events that can be utilized to connect database changes to client handlers:

  • DatabaseInstance.GetReference(string path)
  • Query.ValueChanged
  • Query.ChildAdded
  • Query.ChildChanged
  • Query.ChildRemoved

The first is a method that returns a DatabaseReference at a given path (relative to the database root), while the rest are events that fire from a DatabaseReference (which is a subclass of Query). Using this structure, the client can connect to specific paths for the player’s own Squad (an equivalent of a guild if you’ve ever played an MMORPG) and listen to events for changes in data within that squad.

We have five components for our social Squad features that make use of Realtime Database:

  1. Settings
  2. Members
  3. Chat
  4. Events
  5. Shared Houses

For each of these features, we use handlers for a combination of the events above. For example, we dedicated a parent key called members that includes all key/value pairs for Squad members, and registered ChildAdded, ChildChanged and ChildRemoved event handlers for that parent key. Adding, changing or removing any child object at that point triggers Firebase to send an event to the client, which will then update the client’s internal data and necessary UI elements. Here is a simplified look at how we implemented the event listener for adding new members to the squad:

How to handle adding new Squad Members via Firebase Realtime Database

Updating or removing members within the squad follow a very similar logic. Instead of ChildAdded, the client can also listen to ChildChanged or ChildRemoved to update corresponding memberData, or remove it entirely from the collection.

If the player leaves the Squad or joins a new one, old listeners are unregistered at the time of leaving the Squad, and new listeners are registered when the new Squad is joined.

Bonus: Updating Squad Settings easily using C# Reflection

One way to easily synchronize fields in Unity with the remote database is by using Reflection. This perk of C# especially comes in handy while implementing an event listener for Squad Settings that can be modified via the ChildChanged event. The client can simply listen to the settings parent key for when a child is updated, and update the client representation accordingly.

Using Reflection, the client does not need to contain individual lines of code to update every single setting. Instead, it can dynamically find the field that was changed, and update its value.

How to handle updates to Squad Settings via Firebase Realtime Database

While not functionally required, the use of Reflection can make it simpler to parse many fields under a shared parent key. In our case, having many simple settings within a Squad makes it fitting to dynamically synchronize them with Firebase Realtime Database.

Integrating User Interface

Once the events were set up on Firebase Realtime Database and hooked up on the client event handlers, we were able to connect the event callbacks to UI elements for our Squad window. We use the MVC (Model-View-Controller) design pattern to connect data changes to the UI elements, while keeping the logic for each separate.

The Squad’s feature manager component (Controller) listens to specific paths on the Realtime Database, making adjustments to the appropriate data point (Model), while UI components (View) listen to changes in the data to update the visual representation.

Team view within the Squad window

In the Team view, we have a list of all squad members, as well as information about the currently active Squad Event (which is all about pairing up with another team member). In this case, a Squad teammate in the list has a dedicated Prefab object with a dedicated script to listen to changes in the member data. If a remote member goes offline, changes their player avatar, or if their Squad role is updated, the following steps are triggered:

  1. Remote player requests action from server
  2. Server performs the action and updates the database
  3. Firebase Realtime Database is updated and sends events to clients
  4. Local player receives update event from Firebase Realtime Database
  5. Controller class parses the event to update member Model data
  6. Internal event is triggered to update UI View

Making Squad Chat Work

Chat works somewhat similar to member data in terms of event handlers, but it has some key differences in terms of the content of the data and how often new entries are created. We had to support different types of chat messages in order to show different types of actions or events. We also expected that there would be a constant stream of new chat messages, which means a lot more new entries compared to member data.

Chat view within the Squad window

In order to make sure all messages are in their correct positions as they feed in to the client, we decided to include all message types under the same parent key, and listen to ChildAdded events as new messages are added. Within the structure of a message, we dedicated a type field that will allow us to differentiate between an actual chat message, a system message, or an interactable squad event notification. Based on this field, we also initialize the Prefab differently, such as showing the Player Avatar next to chat messages, or the yellow box for system messages.

Similar to member actions, typing a new message in the input field and tapping on SEND will send a request to the server, which will add the new entry to the database and then trigger the ChildAdded event to be parsed by the clients.

Since this key that contains all messages is expected to grow constantly as new messages are sent, we decided to use the LimitToLast query feature in Firebase Realtime Database, which allowed us to only retrieve the most recent 100 messages in the chat history.

Special Squad Chat Interactivity

One feature we wanted to integrate into our Squad chat was the ability to interact with particular special messages within the chat window itself in order to best reinforce and highlight collaborative gameplay. For this reason we integrated the sharing of Elbow Grease (which serves as an energy-like currency) between squad members, as well as allowing members to form pairs to renovate and flip a house together.

Chat view with special interactive messages

As my teammate, Alex, explained in our previous post, we handled different types of messages within the chat window simply by creating a separate type field.

How Did We Even Get Here?

While Firebase Realtime Database and Firebase’s plugin for Unity provided us the tools to execute on this proprietary system for House Flip’s player community, it could not have been done without the diligence and creativity of FUN-GI’s game design and production team. To conclude our story told backwards, we have to begin with our organizational workflow where Su Dural will walk through how we use Asana’s Premium tier functionality to get from zero to one.

--

--

Osman Kaan Demiroz
Firebase Developers

Sr. Software Engineer @ FUN-GI GAMES. Avid gamer with a passion for photography and classic rock.