1

I writing a mobile application that requires to search for a document that has two fields that satisfy the search query.

I got the original idea of searching in Firestore from this answer

I tried to modify it to get achieve my required result but I'm getting an error. Here is my code which is an extension method on CollectionReference<User>:

CollectionReference<User> get all {
    return FirebaseFirestore.instance.collection('users').withConverter<User>(
      fromFirestore: (snapshot, _) => User.fromFirestore(snapshot),
      toFirestore: (User user, options) => user.toFirestore(),
    );
  }

extension UserQueryExtension on CollectionReference<User> {
  Query<User> search(String search) {
    if (search.isEmpty) {
      return this;
    }

    return where(
      Filter.or(
        Filter.and(
          Filter('name', isGreaterThanOrEqualTo: search),
          Filter('name', isLessThan: '${search}z'),
        ),
        Filter.and(
          Filter('surname', isGreaterThanOrEqualTo: search),
          Filter('surname', isLessThan: '${search}z'),
        ),
      ),
    );
  }
}

When I run the code I get the following error:

Exception has occurred.
PlatformException (PlatformException(error, An error occurred while parsing query arguments, see native logs for more information. Please report this issue., null, null))

I would appreciate the help.

craig_hero
  • 65
  • 10
  • Can you also share the other parts of the query as there are some [Limitations](https://firebase.google.com/docs/firestore/query-data/queries#limitations_3) on `or` queries. – Rohit Kharche Jul 25 '23 at 10:31

1 Answers1

1

As per the official documentation of Firestore Query limitations Make sure your query does not violate the listed conditions in the Query Limitations.

Update :

Oops I am the one who was violating the limitations thanks to @Frank van Puffelen.

You cannot do range queries against multiple fields !.

Workaround :

It is better if you fetch all records and save in the list and then you filter the list based on your needs.

class User {
  User({required this.name, required this.surname});

  User.fromJson(Map<String, Object?> json)
    : this(
        name: json['name']! as String,
        surname: json['surname']! as String,
      );

  final String name;
  final String surname;

  Map<String, Object?> toJson() {
    return {
      'name': name,
      'surname': surname,
    };
  }
}

final userRef = FirebaseFirestore.instance.collection('users').withConverter<User>(
      fromFirestore: (snapshot, _) => User.fromJson(snapshot.data()!),
      toFirestore: (User user, _) => user.toJson(),
    );
// get all
List<QueryDocumentSnapshot<User>> movies = await userRef.get()
      .then((snapshot) => snapshot.docs);

Reference : Typing CollectionReference and DocumentReference

Rohit Kharche
  • 2,541
  • 1
  • 2
  • 13