Firestore dynamic querying in Flutter Fire

Viewed 607

I have a collection of contents, I want to retrieve them applying certain filters under certain circumstances.

I store filter values in a bloc object, this values can be null or not. If it's null, the filter should not apply, if it has a value, the filter applies.

I would like to do something like that:

  CollectionReference contents =
    FirebaseFirestore.instance.collection('content');

  if (_bloc.searchQuery != null && _bloc.searchQuery.isNotEmpty) {
    // Add where criteria here
  }

  if (_bloc.publishUntilQuery != null) {
    // Add where criteria here
  }

  if (_bloc.publishFromQuery != null) {
    // Add where criteria here
  }

  return StreamBuilder<QuerySnapshot>(
    stream: contents.snapshots(),
    builder:
        (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
      // ...
    },
  );

The problem is that I don't know how to construct something like a Query object to later add it to the final search.

How to solve this issue? Many thanks.

1 Answers

As explained in the doc, the CollectionReference class inherits from the Query class. In addition, the methods from the Query class used to refine the Query (e.g. orderBy(), where(), etc...) return a Query. You can therefore use these different methods to refine your initial Query, applying "certain filters under certain circumstances", as follows:

  Query contents =
    FirebaseFirestore.instance.collection('content');

  if (_bloc.searchQuery != null && _bloc.searchQuery.isNotEmpty) {
    contents = contents.where('....', isEqualTo: '....');  // For example, to be adapted
  }

  if (_bloc.publishUntilQuery != null) {
    contents = contents.where('....', isEqualTo: '....');  // For example, to be adapted
  }

  if (_bloc.publishFromQuery != null) {
    contents = contents.where('....', isEqualTo: '....');  // For example, to be adapted
  }

  return StreamBuilder<QuerySnapshot>(
    stream: contents.snapshots(),
    builder:
        (BuildContext context, AsyncSnapshot<QuerySnapshot> snapshot) {
      // ...
    },
  );
Related