【问题标题】:Firebase endAt() funky behaviour with orderByChild() when paging/infinite scroll分页/无限滚动时使用 orderByChild() 的 Firebase endAt() 时髦行为
【发布时间】:2019-07-02 19:36:14
【问题描述】:

我正在尝试首先加载用户的最新帖子并按降序对其进行分页,但在使用 endAt().limitToLast()orderByChild() 时遇到问题。

我可以使用startAt().limitToFirst()orderByChild() 很好地分页项目,但我需要从最后加载我的列表...当使用endAt() 执行我的查询时,orderByChild() 似乎被忽略了。

这是 categories 节点的 JSON

{
  "-LY8EYaWHINB1khsIEvJ" : {
    "Recipies" : true,
    "username" : "User1"
  },
  "-LYDaIrnDKIWndMcLE-g" : {
    "Recipies" : true,
    "username" : "User4"
  },
  "-LY8Em4B6COFk3how5FC" : {
    "Buds" : true,
    "username" : "User2"
  },
  "-LY8Eq2E1muFcOBstODa" : {...},
  "-LY8Esi98QdhszIgvRRN" : {...},
  "-LY9OSc7u8wTNQaJ7BXL" : {...},
  "-LY8EymPGxK8Y_YnRfC0" : {...},
  "-LY8F0RrYbLNPpYwIuMX" : {...},
  "-LY8F3QfERAhOq3iW3jC" : {...},
}

这是我的查询的样子(注意我需要从下往上获取):

  const fetchCategoryImages = (category, currentImages, lastKey) => {
      if (!lastKey) {
        return () => {
          firebase.database().ref('/categories')
            .orderByChild('Recipies' //this is the category)
            .endAt(true)
            .limitToLast(4)
            .on('value', snapshot => {
              const arrayOfKeys = Object.keys(snapshot.val())
                 .sort()
                 .reverse();

              const results = arrayOfKeys
                .map((key) => snapshot.val()[key]);

              const createLastKey = arrayOfKeys[arrayOfKeys.length - 1];

              //just passing the initial data with redux here... (snapshot and lastKey...)
            });
        };
      } else {
         //subsequent fetch if there is a lastKey to reference start point
         return () => {
           firebase.database().ref('/categories')
             .orderByChild('Recipies' //this is the category)
             .endAt(true, '-LY9OSc7u8wTNQaJ7BXL' //this is the lastKey)
             .limitToLast(3)
             .on('value', snapshot => {
               const arrayOfKeys = Object.keys(snapshot.val())
                  .sort()
                  .reverse()
                  .slice(1);

               const results = arrayOfKeys
                  .map((key) => snapshot.val()[key]);

               const createLastKey = arrayOfKeys[arrayOfKeys.length - 1];
               const concatImages = _.concat(currentImages, results);

               //passing the new data with redux here... (snapshot and lasy ley...)

               }
           });
        };
     };

当我简单地将查询切换为使用startAt().limitToFirst()orderByChild() 时,所有这些问题都会消失。

非常感谢我能在这个问题上获得的所有帮助,干杯!

【问题讨论】:

  • 这里发生了很多事情,我们不知道值,因此很难看出问题出在哪里。你能:1)在不依赖于react/redux的sn-p中重现问题吗? 2) 用lastKeycategory 的硬编码值重现它? 3)分享最小的JSON来重现它(作为文本,请不要截图)?您可以通过单击 Firebase Database console 的溢出菜单 (⠇) 中的“导出 JSON”链接来获取此信息。
  • @FrankvanPuffelen 嘿,弗兰克!谢谢,我刚刚更新了我的答案 - 希望这会有所帮助。
  • 这有帮助,谢谢。不过,我仍然很难理解确切的问题。 1)您可以进一步减少代码以仅显示不起作用的情况吗? 2)你能减少对问题的描述,只涵盖不起作用的情况吗?我希望我能在这些变化方面提供更多帮助。
  • @FrankvanPuffelen 由于另一个问题,我打算删除这个问题,我刚看到你的评论,对不起!我编辑了这个问题以匹配另一个问题。
  • 不要删除现有问题然后重新发布。只是澄清你原来的问题。再次重新发布您自己的问题将被标记并提醒版主。

标签: node.js reactjs firebase firebase-realtime-database infinite-scroll


【解决方案1】:

所以,在尝试了几乎所有事情之后,结果我所要做的就是添加startAt(true)。我不确定为什么,但它有效。我还有其他与此几乎相同的查询,但没有它也能正常工作 - 比我... 很想知道为什么我需要它才能让它工作。

这是我的工作代码:

 const fetchCategoryImages = (category, currentImages, lastKey) => {
      if (!lastKey) {
        return () => {
          firebase.database().ref('/categories')
            .orderByChild('Recipies' //this is the category)
            //THE SOLUTION
            .startAt(true)
            .endAt(true)
            .limitToLast(4)
            .on('value', snapshot => {
          const arrayOfKeys = Object.keys(snapshot.val())
             .sort()
             .reverse();

          const results = arrayOfKeys
            .map((key) => snapshot.val()[key]);

          const createLastKey = arrayOfKeys[arrayOfKeys.length - 1];

          //just passing the initial data with redux here... (snapshot and lastKey...)
        });
    };
  } else {
     //subsequent fetch if there is a lastKey to reference start point
     return () => {
       firebase.database().ref('/categories')
         .orderByChild('Recipies' //this is the category)
          //THE SOLUTION
          .startAt(true)
         .endAt(true, '-LY9OSc7u8wTNQaJ7BXL' //this is the lastKey)
         .limitToLast(3)
         .on('value', snapshot => {
           const arrayOfKeys = Object.keys(snapshot.val())
              .sort()
              .reverse()
              .slice(1);

           const results = arrayOfKeys
              .map((key) => snapshot.val()[key]);

           const createLastKey = arrayOfKeys[arrayOfKeys.length - 1];
           const concatImages = _.concat(currentImages, results);

           //passing the new data with redux here... (snapshot and lasy ley...)

           }
       });
    };
 };

【讨论】:

  • 嗯...这有点道理,因为您只想要具有 Recipies 属性的结果。我主要担心的是我无法复制它。请参阅我对数据、代码和链接的回答(因为代码不适合评论)。
【解决方案2】:

我只是用这个 JSON 测试:

{
  "-LY8EYaWHINB1khsIEvJ" : {
    "Recipies" : true,
    "username" : "User1"
  },
  "-LY8Em4B6COFk3how5FC" : {
    "Buds" : true,
    "username" : "User2"
  },
  "-LY8Eq2E1muFcOBstODa" : {
    "Buds" : true,
    "username" : "User3"
  },
  "-LY8Esi98QdhszIgvRRN" : {
    "Buds" : true,
    "username" : "User4"
  },
  "-LY8EymPGxK8Y_YnRfC0" : {
    "Buds" : true,
    "username" : "User5"
  },
  "-LY8F0RrYbLNPpYwIuMX" : {
    "Buds" : true,
    "username" : "User6"
  },
  "-LY8F3QfERAhOq3iW3jC" : {
    "Receipies" : true,
    "username" : "User7"
  },
  "-LY9OSc7u8wTNQaJ7BXL" : {
    "Buds" : true,
    "username" : "User8"
  },
  "-LYDaIrnDKIWndMcLE-g" : {
    "Recipies" : true,
    "username" : "User8"
  }
}

还有这段代码:

ref.orderByChild('Buds')
  .endAt(true, '-LY9OSc7u8wTNQaJ7BXL')
  .limitToLast(3)
  .once('value', snapshot => {
    snapshot.forEach(child => {
      console.log(child.key+": "+JSON.stringify(child.val()));
    })
  })

现场样本:https://jsbin.com/zigofok/edit?js,console

运行时打印:

"-LY8EymPGxK8Y_YnRfC0: {\"Buds\":true,\"username\":\"User5\"}"

"-LY8F0RrYbLNPpYwIuMX: {\"Buds\":true,\"username\":\"User6\"}"

"-LY9OSc7u8wTNQaJ7BXL: {\"Buds\":true,\"username\":\"User8\"}"

注意它是如何跳过 User7 的,因为该用户没有 Buds 属性。

【讨论】:

    猜你喜欢
    • 2016-10-17
    • 1970-01-01
    • 1970-01-01
    • 2019-11-24
    • 1970-01-01
    • 1970-01-01
    • 2023-01-29
    • 1970-01-01
    • 2021-09-17
    相关资源
    最近更新 更多