确定是否所有参与者都已借助云功能采取行动

时间:2018-12-07 02:12:23

标签: google-cloud-firestore google-cloud-functions

我正在尝试使用Firestore数据库创建游戏,为了避免和客户端作弊,我想处理云功能内部的大多数操作。

我当前的Firestore结构如下:

matches: {
   matchID1: {
       //fields
       matchname: "Test match",
       timestamp: 12/6/2018 16:41:05 PM,
       players: [playerID123, playerID345, playerID678],
       //subcollections
       attackPool: {
           attackID123: {
               playerID123: "punch"
           }
           attackID345: {
               playerID123: "kick"
           },
           attackID678: {
               playerID123: "headbutt"
           }
       }
   } 
}

匹配文档应可由客户端读取,但AttackPool仅可由客户端写入。

我这样构造数据,以便用户可以通过调用以下内容来获取他们所涉及的所有匹配项:
 db.collection("matches").where("players", "array-contains", currentUserID)
,但这不会透露由于它们位于子集合中而受到的任何攻击,因此其他玩家的举动必须保密。在所有玩家攻击之后,比赛结束。

我的想法是然后创建云功能,以监视何时将条目写入AttackPool,届时它将捕获AttackPool中的所有攻击并达到父级比赛并抓住所有玩家。然后该功能将检查玩家数组中的每个玩家是否在AttackPool中都有一个条目,如果是,它将确定比赛已完成,确定获胜者,并分出奖励和积分。

到目前为止,这就是我的云功能:

exports.watchMatchAndAttackUpdates = functions.firestore
  .document("matches/{matchId}/attackPool/{attackId}")
  .onWrite((change, context) => {
    //Get all attacks in attack pool
    change.after.ref.parent.get().then(function(querySnapshot) {
      const attackers = [];
      querySnapshot.forEach(function(doc) {
          attackers.push(doc.data())
      });
      //Get match data
      change.after.ref.parent.parent.get().then(res => {
        const matchData = res.data();
        const players = matchData.players;
        //Compare arrays to check that all players moved
        //If so, complete match, divvy rewards
      });
    });
  });

但是,我在这一点上停了下来,因为这一切似乎都确实是错误的。从get()请求隐藏集合的嵌套AttackPool似乎还可以,但是现在我的云函数具有多个DB调用,并且在多个级别/集合之间进行比较。必须有更好的方法。

所以我的问题是,构造这些集合的正确方法是什么?如果这是最好的方法,那么检查所有玩家是否发动进攻的最好方法是什么?

0 个答案:

没有答案