4

I'm using firebase in combination with GeoFire, this works great but I need one more query and I'm not sure how it should be done.

This is my GeoFire/Firebase query:

var geoFire = new GeoFire(ref.child("geoFire"));

var geoQuery = geoFire.query({
    center: [51.315077, 3.73261],
    radius: 100 //kilometers
})

geoQuery.on("key_entered", function(key, location, distance) {

    ref.child("articles").child(key).on("value", function(snap){

        var x = snap.val()
        DATA.push(x)

    })

})

This is my json database in firebase:

geoFire

-JmE05U-Wbr5LGRSh0Z8
-JmE0COUFBRPZIBqwfYN

articles

-JmE05U-Wbr5LGRSh0Z8
   * ...
   * articlePostDate: 2015/04/26 08:00:00
   * ...
-JmE0COUFBRPZIBqwfYN
   * ...
   * articlePostDate: 2015/04/26 12:00:00
   * ...
-JmE0Iq7-uvrk5Tg_K8_
   * ...
   * articlePostDate: 2015/01/26 08:00:00
   * ...
-JmE0MrnstNv9d_8ozQ4
   * ...
   * articlePostDate: 2015/04/26 15:00:00
   * ...

The above GeoFire/Firebase query returns 2 articles (but could be 100+ articles), this is correct.

My question:

How can I extend the Firebase query below so that I can get records based on a range of articlePostDates? For instance, all GeoFire returned records with a post date between 2015/04/26 07:00:00 and 2015/04/26 16:00:00? I think it's with .startAt() and .endAt(), but I'm unsure how.

ref.child("articles").child(key).on("value", function(snap){

    var x = snap.val()
    DATA.push(x)

})

Thx for your advise.

ThunderStruct
  • 1,504
  • 6
  • 23
  • 32
kevinius
  • 4,232
  • 7
  • 48
  • 79
  • You can't combine these in the way you've suggested here. A good alternative would be to archive old articles to another list so you only receive current ones in the `articles/` path, removing the need for the additional filtering. If items number less than a hundred, simple client-side filtering is also a possibility. Explaining the actual use case and constraints, in addition to your proposed solution would save a lot of guesswork for finding a good approach. – Kato Apr 22 '15 at 20:57
  • You managed to solve it, I must do the same – JG_GJ Oct 08 '19 at 18:29

1 Answers1

2

Before using startAt() or endAt(), you need to order your list with orederByChild().

Try the following code (The starting point is inclusive).

ref.child("articles")
.orderByChild('articlePostDate')
.startAt('2015/04/26 07:00:00').endAt('2015/04/26 16:00:00')
.on("value", function(snap){
    var x = snap.val()
    DATA.push(x)
})

For more information please refer to Firebase Query.startAt

Saeed D.
  • 1,125
  • 1
  • 11
  • 23
  • I'm getting an error "Error: b is null". But if i try it without the .child(key) method, it works. I think it has something to do with the GeoFire query, since this returns only 1 record at a time. GeoFire should return a list of items, then i can do the range on the list. – kevinius Apr 22 '15 at 07:46
  • The .child(key) here means you would be ordering and querying on exactly one child, which is probably not sensible unless the children were also collections, which doesn't seem to be the OPs intent. – Kato Apr 22 '15 at 21:00
  • Indeed, i need a collection. GeoFire returns a string that is the ID of an article. I can collect the id's in an array and listen for ref.child().on("value") in geoQuery.on("ready"). But then the question is, how can i get only the articles with the ID's in the array, and still be able to do the date filtering? – kevinius Apr 23 '15 at 05:24
  • Your geoFire list seems to be a subset of your articles list. Create two lists (one from GeoFire and one from filtered articles) then find the common elements using (http://stackoverflow.com/questions/11076067/finding-matches-between-multiple-javascript-arrays) – Saeed D. Apr 23 '15 at 19:28