Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly order data chronologically in my Firebase infinite scroll?

CODE:

<script>

    var app = angular.module('app', ['firebase']);

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


            console.log(<%=lastID%>);

            $scope.data = [];
            var _n = Math.ceil(($(window).height() - 50) / (350)) + 1;
            var _start = <%= lastID %>;
            var _end = <%= lastID %> + _n - 1;

            $scope.getDataset = function() {

                fb.orderByChild('id').startAt(_start).endAt(_end).limitToLast(_n).on("child_added", function(dataSnapshot) {

                    $scope.data.push(dataSnapshot.val());
                    $scope.$apply()
                    console.log("THE VALUE:"+$scope.data);

                });

                _start = _start + _n;
                _end = _end + _n;

            };


            $scope.getDataset();

            window.addEventListener('scroll', function() {
                 if (window.scrollY === document.body.scrollHeight - window.innerHeight) {
                      $scope.$apply($scope.getDataset());
                 } 
            });

    });

    // Compile the whole <body> with the angular module named "app"
    angular.bootstrap(document.body, ['app']);


</script>

SITUATION:

lastID is the ID of the last post created. They go backwards (from -1 to lastID).

This solution works perfectly except when some posts are deleted.

(Posts are ordered from latest to oldest (from lastID to -1)).

For example, if there are 16 posts, lastID = -16.

If I delete posts -13 to -5 and post -3, lastID stays at -16.

Which means that when the page loads, no posts appear after the 3 first posts (-16 to -14) are loaded and I need to scroll repeatedly down to get post -4 to appear.


QUESTION:

How can I make sure that if some posts are deleted, my Infinite Scroll script will skip the ids of the inexisting posts and just load the 3 closest posts ?


WHAT I CHECKED:

I looked at this:

Display posts in descending posted order

But I am not sure as to how I would implement those solutions inside my infinite scroll. Any ideas ?

like image 774
Coder1000 Avatar asked Dec 25 '16 17:12

Coder1000


3 Answers

If I understood you correctly, you don't have to use end. This could be achieved using startAt + limit

fb.orderByChild('id').startAt(_start).limit(n)...

And use a layout to order items descending. Using this you don't have to worry about sequence of ids if they are consecutive

UPDATE

You can do this even simpler. Just update your start with a latest value

fb.orderByChild('id').startAt(_start).limit(_n).on("child_added", function(dataSnapshot) {

    $scope.data.push(dataSnapshot.val());
    $scope.$apply()
    _start = dataSnapshot.child('id').val()
    console.log("THE VALUE:"+$scope.data);

});

In this case your _start will always hold the last id and you may not worry about deleted elements. Alternatively you may use a temporary variable to store last id value and use it in startAt

like image 139
Nikolay Osaulenko Avatar answered Oct 21 '22 01:10

Nikolay Osaulenko


Basically all data saved in Firebase is ordered chronologically, since the auto-generated id for each record is based on the timestamp. Hence you don't need to order your values. Just make sure you are adding a new id in the key value pair being saved in Firebase.

In case you want to reverse the order of the list (making the most recent records appear at the top), you will need to reverse the list after reading it.

EDIT

If you want to get the position of your record in the database, you can use something similar to the following:

var ref = new Firebase("https://dinosaur-facts.firebaseio.com/dinosaurs");
ref.orderByKey().on("child_added", function(snapshot) {
  console.log(snapshot.key() + " was " + snapshot.val().height + " meters tall");
});

You can find more information about ordering here.

like image 38
Michele La Ferla Avatar answered Oct 21 '22 00:10

Michele La Ferla


startAt and limitToFirst can be used to retrieve next posts.

Just tell firebase to start after id of last loaded post (start + 1 in this case), and deleted id will be skipped automatically.

var itemsPerScroll = 1;
$scope.getDataset = function() {
  var start = $scope.data.slice(-1)[0].id
  fb.orderByChild('id').startAt(start + 1).limitToFirst(itemsPerScroll)
  .on("child_added", function(dataSnapshot) {
    $scope.data.push(dataSnapshot.val());
    $scope.$apply()
  })
}
like image 23
DarkKnight Avatar answered Oct 21 '22 01:10

DarkKnight