I am trying to just retrieve a list of records, sorted by one of the fields in each record, and I would like to be able to retrieve the data in pages.
According to the Firebase documentation, the reference.startAt()
method has an optional 2nd parameter, which is:
The child key to start at. This argument is only allowed if ordering by child, value, or priority.
First off, here is the data:
{
"products" : {
"-KlsqFgVWwUrA-j0VsZS" : {
"name" : "Product 4",
"price" : 666
},
"-Klst-cLSckuwAuNAJF8" : {
"name" : "Product 1",
"price" : 100
},
"-Klst7IINdt8YeMmauRz" : {
"name" : "Product 2",
"price" : 50
},
"-Klst9KfM2QWp8kXrOlR" : {
"name" : "Product 6",
"price" : 30
},
"-KlstB51ap1L2tcK8cL6" : {
"name" : "Product 5",
"price" : 99
},
"-KlstDR5cCayGH0XKtZ0" : {
"name" : "Product 3",
"price" : 500
}
}
}
And here is the code which is able to retrieve Page 1 (lowest priced item + 2nd lowest priced + 3rd lowest priced):
(I am using Firebase JS SDK 4.1.1)
'use strict';
var firebase = require('firebase');
firebase.initializeApp({
apiKey: "your-api-key",
authDomain: "your-firebase-domain",
databaseURL: "https://your-db.firebaseio.com",
projectId: "your-project",
storageBucket: "your-bucket.appspot.com",
messagingSenderId: "your-sender-id"
})
firebase.database().ref('products')
.orderByChild('price')
.limitToFirst(3)
.on('child_added', function (snapshot) {
var key = snapshot.key;
var data = snapshot.val();
console.log(key + ': ' + JSON.stringify(data))
})
Output:
TJ:database tjwoon$ node test.js
-Klst9KfM2QWp8kXrOlR: {"name":"Product 6","price":30}
-Klst7IINdt8YeMmauRz: {"name":"Product 2","price":50}
-KlstB51ap1L2tcK8cL6: {"name":"Product 5","price":99}
Page 2 should be the 3rd lowest, 4th lowest, and 5th lowest priced products, which means my code need one additional line:
firebase.database().ref('products')
.orderByChild('price')
.startAt(null, '-KlstB51ap1L2tcK8cL6')
.limitToFirst(3)
.on('child_added', function (snapshot) {
var key = snapshot.key;
var data = snapshot.val();
console.log(key + ': ' + JSON.stringify(data))
})
Output:
TJ:database tjwoon$ node test.js
-Klst9KfM2QWp8kXrOlR: {"name":"Product 6","price":30}
-Klst7IINdt8YeMmauRz: {"name":"Product 2","price":50}
-KlstB51ap1L2tcK8cL6: {"name":"Product 5","price":99}
The problem is that it is returning Page 1 again. If the documentation is correct, the results should start at the record with key -KlstB51ap1L2tcK8cL6
.
I have tried adding an .indexOn
rule for the price field, but the results remained identical.
If I remove the orderByChild()
line, then the results do start from the given key, but of course the sorting is incorrect, plus it behaves contrary to the documentation...
I found these other Stack Overflow posts which describe the same problem:
- Firebase orderByChild with startAt()'s second argument w/ pagination not odering
- (see comment below. I don't have enough reputation to include the link here)
However there are no answers to those questions and quite few responses. There are no issues in the Github repository which match the search term startat
.
Is anyone else facing the same issue? This problem makes it impossible to retrieve a sorted list in a paginated manner...