6

I attempted to use an 'OR' || statement in the equalTo() method, but this does not seem to work. Do I have to make a separate call for each value or is there a way to make conditional queries in firebase?

export const startSetContent = () => {
  return (dispatch, getState) => {
    const ref = database.ref("content");
    return ref
      .orderByChild("category")
      .equalTo('one-act-play' || 'ten-min-play' || 'full-length-play')
      .once('value')
      .then(snapshot => {
        const content = [];
        snapshot.forEach(childSnapshot => {
          content.push({
            id: childSnapshot.key,
            ...childSnapshot.val()
          });
        });
        dispatch(setContent(content));
      });
  };
}; 
Jordan Hensley
  • 420
  • 7
  • 18
  • Firebase doesn't provide a way to use conditional queries. Have a look at [this answer](https://stackoverflow.com/a/29564075/5861618) for more details. – Rosário Pereira Fernandes Jan 12 '18 at 23:55
  • 1
    You might also want to have a look at [Firestore](https://firebase.google.com/docs/firestore/) which provides better query features than the Realtime Database – Rosário Pereira Fernandes Jan 13 '18 at 00:04
  • Is firestore stable enough to use in production? I saw It was still in beta so I am a little weary to dive in. – Jordan Hensley Jan 13 '18 at 00:22
  • 1
    @RosárioPereiraFernandes Unfortunately [Firestore also doesn't support OR conditions](https://stackoverflow.com/questions/46632042/how-to-perform-compound-queries-with-logical-or-in-cloud-firestore). – Frank van Puffelen Jan 13 '18 at 03:27

2 Answers2

3

What you typed there was a logical OR that JavaScript the programming language interprets. The result of the expression:

'one-act-play' || 'ten-min-play' || 'full-length-play'

is going to be simply:

'one-act-play'

So, Firebase Realtime Database will not see what you're trying to tell it.

Firebase Realtime Database has no concept of a kind of query that has ORs in it. You will have to query each type of thing separately and merge them together in your code as needed.

Doug Stevenson
  • 297,357
  • 32
  • 422
  • 441
  • Firebase does not have the best query possibilities at the moment, so you have to keep this is mind. That's the reason we have switched to Mongo. – Michal Takáč Jan 12 '18 at 23:58
1

There is no concept of doing that you are asking for. You can do a turn around in which you can get the values on basis of one filter one-act-play using equalTo and rest you can filter on user end like:

export const startSetContent = () => {
  return (dispatch, getState) => {
    const ref = database.ref("content");
    return ref
      .orderByChild("category")
      .equalTo('one-act-play')
      .once('value')
      .then(snapshot => {
        const content = [];
        Object.keys(snapshot.val()).map(k => {
        if(k == 'ten-min-play' || k == 'full-length-play'){
        snapshot.forEach(childSnapshot => {
          content.push({
            id: childSnapshot.key,
            ...childSnapshot.val()
          });
        });
        }
        dispatch(setContent(content));
      });
  };
}; 

Or you can use library made to fulfil this kind of requirement Querybase

Himanshu
  • 12,071
  • 7
  • 46
  • 61