Firebase:如何加载热门帖子而没有类似评分的帖子被跳过?

时间:2017-07-03 18:17:49

标签: javascript node.js firebase firebase-realtime-database

我使用firebase在我的网络应用程序中实现了无限滚动。

在我的" Top"部分,我展示了用户的最高投票帖。

问题是,在我目前的实施中,跳过了一些帖子。

也就是说,如果很多帖子的分数相同,有些则不会出现。

我理解为什么会发生这种情况,我将我的帖子加载了12个,然后选择下一个批次:

start = childDataSnapshot.child("inversedScore").val() + 1;

这种方法的问题在于,如果有超过12个元素具有相同的投票得分,或者如果有2个元素具有相同的投票得分,一个是数字12而另一个数字是13,那么数字13将被忽略我们直接进入下一个得分水平。

例如,这是我在服务器上的数据:

post1: score: 15
post2: score: 14
post3: score: 13
post4: score: 12
post5: score: 11
post6: score: 10
post7: score: 10
post8: score: 9
post9: score: 9
post10: score: 9
post11: score: 8
post12: score: 7

//posts 13 and 14 will be ignored
post13: score: 7
post14: score: 7

post15: score: 6
post16: score: 6

以下是我将在客户端上看到的内容:

post1: score: 15
post2: score: 14
post3: score: 13
post4: score: 12
post5: score: 11
post6: score: 10
post7: score: 10
post8: score: 9
post9: score: 9
post10: score: 9
post11: score: 8
post12: score: 7
post15: score: 6
post16: score: 6

还有什么方法可以加载带有firebase的热门帖子,这样得分相同的热门帖子永远不会被跳过" ?

客户端:

var started = false;

app.controller('ctrl', function ($scope, $firebaseArray, $timeout) {

    if(started == false) {
        started = true;

        $scope.bricks = [];
        var _n = 12;

        if ( $(window).width() < 992) {
          _n = 2;
        } 

        var firstElementsLoaded = false;
        var _start = -1000000000;
        var position = 0;

        $scope.getDataset = function() {  
            var sendObject = {
                start: _start,
                section: section,
                n: _n,
            } 
            $.ajax({
                type: "POST",
                url: "images/top",
                data: sendObject,
            }).done(function(result) {
                for (var i = 0; i < result.array.length; i++) {
                    console.log("result: "+result.array[i]);
                    $scope.bricks.push(result.array[i]);
                    $scope.$apply();
                }

                _start = result.start;
                firstElementsLoaded = true;
            });
        };


        $scope.getDataset();

        var screenHeight;
        var existingScreenHeight

        if ( $(window).width() < 992) {
            screenHeight = (_n + 1) * 350;
            existingScreenHeight = -350;
        } 
        else {
            screenHeight = 1 * Math.ceil($(window).height()); 
            existingScreenHeight = -screenHeight;
        }

        window.addEventListener('scroll', function() {

            if (firstElementsLoaded == true) {
               if (window.scrollY >= ((screenHeight) + existingScreenHeight)) {
                  existingScreenHeight += (screenHeight);
                  $scope.$apply($scope.getDataset());
                  firstElementsLoaded = false;
               }
            }
        });
    }
});

angular.bootstrap(document.body, ['app']);

服务器

router.post('/images/top', function(req, res, next) {
    var start = parseInt(req.body.start);
    var section = req.body.section;
    var n = parseInt(req.body.n);
    var returnArray = [];
    var screenshotRef = admin.database().ref("posts/"+section);
    screenshotRef.orderByChild("inversedScore").startAt(start).limitToFirst(n).once("value", function(dataSnapshot) {

        dataSnapshot.forEach(function(childDataSnapshot) {

            start = childDataSnapshot.child("inversedScore").val() + 1;

            var post = childDataSnapshot.val();

            var file = bucket.file(post.image);

            var config = {
              action: 'read',
              expires: Date.now() + global.expiryTime,
            };

            file.getSignedUrl(config, function(err, url) {
                if (err) {
                    console.error(err);
                    return;
                }
                post.image = url;
                returnArray.push(post);
                if (returnArray.length == n) {
                    var returnObject = {
                        start: start,
                        array: returnArray
                    }
                    res.send(returnObject);
                }
            });
        });  
    });
});

1 个答案:

答案 0 :(得分:2)

您可以轻松跳过客户端中的额外项目(通常称为锚项)。您无法在查询中跳过它。如果将锚项的键作为第二个参数传入,则可以确保只有一个重叠项。

请参阅以前的这些问题:

如果您对此有疑问,请告诉我,因为它绝对不是API中最直观的部分。