1

So my data structure looks like this:

enter image description here

So in order to display user reservations I need to query by uID and date

return this.firebase.database.list('/reservations', {
  query: {
    orderByChild: 'uID',
    equalTo: uID
  }
});

How can I add the date field to my query to be bigger then current date?

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Uffo
  • 9,628
  • 24
  • 90
  • 154
  • 1
    I think would be better if you save your date in timestamp in this way you'll save 2 fields in your db and of course in your response – Arnold Gandarillas Oct 07 '17 at 16:10
  • Firebase Realtime Database queries can only order/filter on a single property. In many cases it is possible to combine the values you want to filter on into a single (synthetic) property, e.g. `"uID_date": "L6Vgg...Jj2_2017-07-03"`. For an example of this and other approaches, see my answer here: http://stackoverflow.com/questions/26700924/query-based-on-multiple-where-clauses-in-firebase – Frank van Puffelen Oct 07 '17 at 16:16
  • You should store dates in a format that allows querying them. That means you either store them as a timestamp, as @arkgast says, or in a string format that allows lexicographical sorting, e.g. "2017-07-03T19:30:00Z". Also see my answer here: https://stackoverflow.com/questions/38216858/firebase-query-by-date-string – Frank van Puffelen Oct 07 '17 at 16:18

1 Answers1

0

Problem is that Realtime database can be queried by only one field at a time. So the way to go might be:

  • Run query on dates and return who's valid;
  • On each reservation add one more field - uID_dateValid that takes the uid string and simply adds valid to it - KGHFHJKJ_VALID
  • Now just run query on newly added field and return result to your component.

So in your case it would be something like:

const dateValid$ = this.firebase.database.list('/reservations', {
  var currentTime = new Date().getTime();
  query: {
    orderByChild: 'date',
    startAt: currentTime
  }
});

// just to note - you might not need three rows like you have now - 
// "date", "dateTime", "time". You can save one row where value is a 
// timestamp, like in my variable "currentTime" above.

dateValid$.map(items => items.map(item => {
  var key = item.$key;
  var uID_dateValid = item.uID + '_VALID';
  dataToSave[`reservations/${key}/uID_dateValid`] = uID_dateValid;
  return this.firebaseUpdate(dataToSave);
})).subscribe();

And now you can query that and return:

return this.firebase.database.list('/reservations', {
  var valid = uID + '_VALID'; 
  query: {
    orderByChild: 'uID_dateValid',
    equalTo: valid
  }
});

There might be some syntax or minor logic mistakes, but the idea is clear.

Other way would be, just to query database twice, get both lists and filter them on client side.

And one more way might be to query twice, get those two Observables, find the matching records and return Observable of those keys, but in context of streams I am a bit unsure how this could be done..

Julius Dzidzevičius
  • 10,775
  • 11
  • 36
  • 81