从另一个孩子排序后设置一个孩子的值

时间:2018-09-01 14:25:32

标签: node.js firebase firebase-realtime-database google-cloud-functions

我想做的是将questsLeaderboard下的前3名(按score排序,然后用这些新的前3名替换questsTop中的现有子级。

因此,如果questsLeaderboard看起来像:

- questsLeaderboard
  - uid1
    - score: 12
    ...
  - uid2
    - score: 3
    ...
  - uid3
    - score: 10
    ...
  - etc

我希望questsTop像这样:

- questsTop
  - first
    - score: 12
    ...
  - second
    - score: 10
    ...
  - third
    - score: 3
    ...

我已经尝试过了:

export const updateBoards = functions.https.onRequest((req, res) => {
  let questsArr = [];
  const questsRef = db.ref('questsLeaderboard');
  const questsTopRef = db.ref('questsTop');


  questsRef.orderByChild('score').limitToLast(3).on('child_added', (snapshot) => {
    questsArr.unshift(snapshot);
  });

  if (questsArr.length === 3) {
    questsTopRef.set({
      first: questsArr[0],
      second: questsArr[1], 
      third: questsArr[2]
    })
    .then(() => {
      res.status(200).send('top quests set');
    })
    .catch(err => {
      res.status(500).send(err);
    })
  }

})

但是会给出超时错误。我该怎么办?

1 个答案:

答案 0 :(得分:0)

您不能在Cloud Functions中可靠地使用on(),因为侦听器将保持活动状态。另外:如果分数少于3分,您的代码会怎样? if (questsArr.length === 3)永远不会是真实的,也永远不会将结果发送回客户端。

您将改为使用once("value"侦听器,如下所示:

export const updateBoards = functions.https.onRequest((req, res) => {
  let questsArr = [];
  const questsRef = db.ref('questsLeaderboard');
  const questsTopRef = db.ref('questsTop');


  return questsRef.orderByChild('score').limitToLast(3).once('value', (snapshot) => {
    snapshot.forEach(function(child) {
      questsArr.unshift(child);
    })
    return questsTopRef.set({
      first: questsArr[0],
      second: questsArr[1], 
      third: questsArr[2]
    })
    .then(() => {
      return res.status(200).send('top quests set');
    })
    .catch(err => {
      return res.status(500).send(err);
    })
  });
})

您还将注意到,我向所有异步数据库操作中添加了return语句,以确保Cloud Functions可以在读取和写入完成之前使您的函数保持活动状态。有关更多信息,请参见second example in this documentation section