【问题标题】:Set a child's value after sorting from another child从另一个孩子排序后设置一个孩子的值
【发布时间】:2018-09-01 23:55:15
【问题描述】:

我要做的是拉出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);
    })
  }

})

但它给出了超时错误。我能做什么?

【问题讨论】:

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


    【解决方案1】:

    您无法在 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

    【讨论】:

    • 感谢您的回复,我已将其更改为您的答案,但它在哪里 forEach 它告诉我 Argument of type '(child: DataSnapshot) => void' is not assignable to parameter of type '(a: DataSnapshot) => boolean'. Type 'void' is not assignable to type 'boolean'. 在删除 forEach 并使用 unshift(snapshot) 后,我控制台报错Reference.set failed: First argument contains a function in property 'questsTop.first.node_.children_.comparator_'
    • 我刚刚修复了那个循环中的一个错误(我应该推送child而不是snapshot)。但我认为这不会导致您遇到的错误。我不确定这个错误来自哪里。
    • 是的,forEach 循环的function 部分带有下划线,因此错误未修复:/。而且我认为将 questsArr[num] 设置为值存在问题。
    猜你喜欢
    • 2020-08-12
    • 1970-01-01
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    • 2012-02-09
    • 2013-09-15
    • 2013-03-12
    • 1970-01-01
    相关资源
    最近更新 更多