🐌

【Flutter】Firestoreのクエリからvarを無くしたくて

2023/11/19に公開

Firestore のクエリをメソッドチェーンで良い感じにつなげられる拡張メソッドを考えたので紹介します!もし自分に合いそうだなと思ったら是非導入してみてください!

拡張メソッド
extension QueryX<T> on Query<T> {
  /// 適用条件が true の場合にのみ WHERE 句を適用する [where] の拡張メソッド
  Query<T> conditionalWhere(
    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,
    required bool Function() apply,
  }) =>
      apply.call()
          ? where(
              field,
              isEqualTo: isEqualTo,
              isNotEqualTo: isNotEqualTo,
              isLessThan: isLessThan,
              isLessThanOrEqualTo: isLessThanOrEqualTo,
              isGreaterThan: isGreaterThan,
              isGreaterThanOrEqualTo: isGreaterThanOrEqualTo,
              arrayContains: arrayContains,
              arrayContainsAny: arrayContainsAny,
              whereIn: whereIn,
              whereNotIn: whereNotIn,
              isNull: isNull,
            )
          : this;
}

使い方

次のコードでは、ユーザ一覧を Firestore から取得してきます。もし引数に prefecture の指定があれば WHERE 句を追加しています。

個人的に、var が嫌いなんですよね。。。どうにかして var を無くして、良い感じでメソッドチェーンでつなげられないか。。。

修正前のサンプルコード
  Future<List<User>> fetchUsers({
    Prefecture? prefecture,
  }) async {
    var query = FirebaseFirestore.instance
        .collection('users')
        .orderBy('createdAt', descending: true);
    if (prefecture != null) {
      query = query.where('prefecture', isEqualTo: prefecture.name);
    }
    final snapshot = await query.get();
    return snapshot.docs.map((e) => e.toUser()).toList();
  }

そこで考えたが、先ほどの拡張メソッド conditionalWhere() です! WHERE 句を適用するかどうかの条件式を追加できるので、メソッドチェーンでつなげられて var 使わずに済みます!

修正後のサンプルコード
  Future<List<User>> fetchUsers({
    Prefecture? prefecture,
  }) async {
    final snapshot = await FirebaseFirestore.instance
        .collection('users')
        .orderBy('createdAt', descending: true)
        .conditionalWhere(
          'prefecture',
          isEqualTo: prefecture?.name,
          apply: () => prefecture != null,
        )
        .get();
    return snapshot.docs.map((e) => e.toUser()).toList();
  }

以上!

最後に

Flutter 大学という Flutter エンジニアに特化した学習コミュニティに所属しています。オンラインでわいわい議論したり、Flutter の最新情報をゲットしたりできます!ぜひ Flutter 界隈を盛り上げていきましょう!

https://flutteruniv.com?invite_id=9hsdZHg0qtaMIr6RPRulAaRJfA83

Discussion