Question

How do you implement infinite scroll on data that you get from firebase. So far I found an angularjs directive, that works really great but I'm having difficulty implementing it with fireable as firebase returns all data in one single request and this is not what I want.

Was it helpful?

Solution

Few weeks ago, I made a JS function that allowed an infinite scrolling in my app.

First, a set of data is displayed when the user visit the website:

// Add a callback that is triggered for each message.
var n = 25; // Step size for messages display.
$(window).load(function() {
lastMessagesQuery = messagesRef.limit(n); 
lastMessagesQuery.on('child_added', function (snapshot) {
  var message = snapshot.val();
  $('<div/>').text(message.text).prependTo($('#messagesDiv'));
  $('#messagesDiv')[0].scrollTop = $('#messagesDiv')[0].scrollHeight;
});
$('#messagesDiv').fadeTo(1000, 1);
});

Then, the function that makes possible the infinite scrolling:

// Pagination.
var i = 0; // Record variable.
function moreMessages () { 
i += n; // Record pagination updates. 
moreMessagesQuery = messagesRef; // Firebase reference.
moreMessagesQuery.on('value', function (snapshot) {
  var data = snapshot.exportVal(); // Fetch all data from Firebase as an Object.
  var keys = Object.keys(data).reverse(); // Due to the Keys are ordered from the oldest to the newest, it nessesary to change its sequence in order to display Firebase data snapshots properly.
  var total_keys = Object.keys(data).length;
  var k = keys[i]; // Key from where to start counting. Be careful what Key you pick.
  if (i < total_keys) { // Stop displaying messages when it reach the last one.
    lastMessagesQuery = messagesRef.endAt(null, k).limit(n); // Messages from a Key to the oldest.
    lastMessagesQuery.on('child_added', function (snapshot) {
      var message = snapshot.val();
      $('<div/>').text(message.text).appendTo($('#messagesDiv')).hide().fadeIn(1000); // Add set of messages (from the oldest to the newest) at the end of #messagesDiv.
    });
  }  
});
}

Finally, the infinite scrolling:

// Load more messages when scroll reach the bottom.
$(window).scroll(function() { 
if (window.scrollY == document.body.scrollHeight - window.innerHeight) {
  moreMessages();
}  
}); 

It works great with small data sets. I hope this helps you to solve your problem (or gives you more ideas).


UPDATE October 2015

Firebase has growth since my original response, which means now it's pretty easy to achieve an infinite scrolling just using its Javascript API:

First, I recommend to create an Index in your Firebase. For this answer, I create this one:

{
   "rules": {
      ".read": true,
      ".write": false,
      "messages": {
         ".indexOn": "id"
      }
   }
}

Then, let's make some magic with Firebase:

// @fb: your Firebase.
// @data: messages, users, products... the dataset you want to do something with.
// @_start: min ID where you want to start fetching your data.
// @_end: max ID where you want to start fetching your data.
// @_n: Step size. In other words, how much data you want to fetch from Firebase.
var fb = new Firebase('https://<YOUR-FIREBASE-APP>.firebaseio.com/');
var data = [];
var _start = 0;
var _end = 9;
var _n = 10;
var getDataset = function() {
   fb.orderByChild('id').startAt(_start).endAt(_end).limitToLast(_n).on("child_added", function(dataSnapshot) {
      data.push(dataSnapshot.val());
   });
   _start = _start + _n;
   _end = _end + _n;
}

Finally, a better Infinite Scrolling (without jQuery):

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

I'm using this approach with React and it's blazing fast no matter how big your data is.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top