flutterfire icon indicating copy to clipboard operation
flutterfire copied to clipboard

🐛 [cloud_firestore] Overload `Query.where` to Accept a Map for Dynamic Query Construction

Open alissonoliveira opened this issue 1 year ago • 0 comments

Feature Request: Overload Query.where to Accept a Map for Dynamic Query Construction

Problem Statement

The current signature of the Query.where method in Firestore mandates setting each query parameter in a controlled manner. This method becomes cumbersome and less maintainable, particularly in scenarios where it is common practice to isolate the database infrastructure within an independent data access module. This module is often designed to be reused across different applications to promote code reuse and separation of concerns. With introduction of the ability to query on null fields, adapting the current method signature to accommodate this functionality results in extensive and complex conditional logic. Developers are forced to write more code to manage the presence or absence of query parameters, leading to bloated and less readable code.

Proposed Solution

To address this issue and facilitate integration with isolated data access modules, I propose adding an overloaded version of the Query.where method that accepts a Map of parameters. This would allow for more dynamic and concise query construction, as developers could programmatically build the Map based on the specific conditions required by each application that reuses the data access module.

Current Method Signature

Query<T> where(
  Object field, {
    Object? isEqualTo,
    Object? isNotEqualTo,
    Object? isLessThan,
    Object? isLessThanOrEqualTo,
    Object? isGreaterThan,
    Object? isGreaterThanOrEqualTo,
    Object? arrayContains,
    Iterable<Object?>? arrayContainsAny,
    Iterable<Object?>? whereIn,
    Iterable<Object?>? whereNotIn,
    bool? isNull,
  }
)

Proposed Method Signature

Query<T> where(
  Object field, 
  Map<String, Object?> params
)

Example Usage

With the proposed overload, developers could build queries like this:

const notSetParam = Object();
var queryBuilding = null;

for (final q in queries /*queries from app layer*/) {
  var params = <String, Object?>{};

  if (q.isEqualTo != null && !identical(q.isEqualTo, notSetParam)) {
    params["isEqualTo"] = q.isEqualTo;
  } else if (q.isEqualTo == null) {
    params["isEqualTo"] = null;
  }

  // ... similar checks for other conditions

  queryBuilding = (queryBuilding ??  _collection).where(q.field, params);
}

This approach would significantly reduce the complexity and verbosity of the code required to build queries, making it easier to maintain and understand.

Thank you for considering this feature request.

alissonoliveira avatar Jan 25 '24 20:01 alissonoliveira