简体   繁体   中英

Conditional where query on Firestore

I've tried implementing the solutions here:

Conditional where clause in firestore queries

Firestore: Multiple conditional where clauses

But they do not seem to work (see code examples below). Has Firestore changed anything? Am I messing up something in the code below?

Thanks in advance!

For context, the below is in a useEffect hook inside a react functional component. However, I do not believe that is relevant, as the working example below (without the conditional queries) works fine.

Basic example - filter hard coded - works fine. The filter is applied

const query = db.collection('todos')
    .where('userId', '==', userId)
    .where('status', '==', 'pending');

query.onSnapshot((res) => {
  const todos = [];
  res.forEach((todo) => {
    todos.push(todo.data());
  });
});

Does NOT work - returns results that have all statuses. The where query within the IF block has not been applied

const query = db.collection('todos').where('userId', '==', userId);

if (filter === 'complete') {
  query.where('status', '==', 'pending');
}
if (filter === 'complete') {
  query.where('status', '==', 'complete');
}
query.onSnapshot((res) => {
  const todos = [];
  res.forEach((todo) => {
    todos.push(todo.data());
  });
});

Another example to ensure that the if block itself is not the issue here. An initial query created and a 'where' condition added after it (but before the onSnapshot). In this instance, the userId where clause is applied, however the status where clause is ignored. All status todo's are returned

const query = db.collection('todos').where('userId', '==', userId);

query.where( 'status', '==', 'pending' ); // This 'where' clause is being ignored

query.onSnapshot((res) => {
  const todos = [];
  res.forEach((todo) => {
    todos.push(todo.data());
  });
});

You're not following the pattern correctly in the question you cited .

You have to re-assign the query object every time you want to add a new condition. Simply calling where repeatedly doesn't do what you want. where returns a whole new query object every time it's called. You have to continue building on that object, not the original one.

// use LET, not CONST, so you can ressign it
let query = db.collection('todos').where('userId', '==', userId);

// Reassign query, don't just call where and ignore the return value
if (filter === 'complete') {
  query = query.where('status', '==', 'pending');
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM