Tikhon Belousko
Tikhon Belousko

Reputation: 777

Firebase game matching algorithm

I'm trying to create player matching algorithm. So basically I expected it to work like that:

Algorithm:

  1. Player creates game request specifying bet and gameType.
  2. Server subscribes to following some query so from this list:

{
  'gameRequests': {
    '1': {
      createdAt: 1454777718074,
      uid: 123,
      bet: 10,
      gameType: 'nhl'
    },
    '2': {
      createdAt: 1454777718075,
      uid: 123,
      bet: 20,
      gameType: 'nhl'
    },
    '3': {
      createdAt: 1454777718076,
      uid: 321,
      bet: 10,
      gameType: 'nhl'
    },
  }
}

I would get requests with keys '1', '3'.


  1. Now i just delete children with keys '1', '3' and create a game for them.

What I have:

So far I'm doing it by loading the whole gameRequests branch.

randomGamesRef.on('value', onGameRequestsUpdate)

function onGameRequestsUpdate (snapshot) {
    const gameRequests = snapshot.val()

    const pairs = _.chain(gameRequests)
      // Transform to array
      .values()

      // Group by sport and bet size
      .groupBy((req) => req.gameType + '+' + req.bet)

      // Map groups to pairs
      .map((group) => {
        return _.chain(group)
          .uniqBy('createdBy')
          .take(2)
          .value()
      })
      .filter((pairs) => pairs.length === 2)
      .value()

    // Now having this pairs I can delete them 
    // from the database and create new game
  }

But loading everything to memory every time doesn't seem like a good idea.

Question: How would you implemented it in Firebase?

Upvotes: 1

Views: 1032

Answers (1)

Frank van Puffelen
Frank van Puffelen

Reputation: 599776

In NoSQL you often end up modeling your data for the way you want to access it in your code. So instead of reading all game requests and then grouping them by gameType and bet in code, consider storing them under a key that combines gameType and bet:

{
  'gameRequests': {
    'nhl_10': {
      '1': {
        createdAt: 1454777718074,
        uid: 123,
      },
      '3': {
        createdAt: 1454777718076,
        uid: 321,
      }
    },
    'nhl_20': {
      '2': {
        createdAt: 1454777718075,
        uid: 123,
      }
    }
  }
}

Now you code becomes:

function onGameRequestsUpdate (snapshot) {
   snapshot.forEach(function(gametypeSnapshot) {
     if (gametypeSnapshot.numChildren() >= 2) {
       // there is at least one request pair for this game type
     }
   });
};

I keep recommending people to read this article, since it explains NoSQL Data Modeling techniques such as this one.

Upvotes: 1

Related Questions