🎉

設計パターン

2021/09/18に公開

ファイル構成
main.dart
goal.dart(エンティティ)
goal_repository(レポジトリ)

◆fromMapメソッド
DartからJSONに変えるメソッドです。

◆ToMapメソッド
JSONからDartに変えるメソッドです。

◆CopyWithメソッド
特定のフィールドの値を入れ替えたい場合に使えるメソッドです。

◆DocumentReference型
他のコレクションやサブコレクションへ参照することができる。

◆DocumentSnapshotとは
DocumentSnapshotは、DocumentReferenceから得られるスナップショットで、単一のドキュメントデータを持っています。

◆CollectionReferenceとは
コレクションやサブコレクションへの参照ができる。

エンティティの作成

import 'package:cloud_firestore/cloud_firestore.dart';

//エンティティ
class Goal {
  /*タイトル*/
  final String title;

  /*目標*/
  final String goal;

  /*取り組む時間*/
  final String time;
  
  //自分のref情報(これを持しておくことで、delete とか update とかできていろいろ便利)
  //他のコレクションやサブコレクションへ参照することができる。
  final DocumentReference? ref;

  const Goal({
    required this.title,
    required this.goal,
    required this.time,
    this.ref,
  });

//fromMapメソッド:DartからJSONに変えるメソッドです。
  factory Goal.fromMap(Map<String, dynamic> map) {
    return new Goal(
      title: map['title'],
      goal: map['goal'],
      time: map['time'],
      
      // この情報は map には含まれていないので取れないのでコメントアウト
      //ref: map['ref'],
    );
  }

  //

  ///このメソッドの目的は、Goalクラスにref情報をもたすと言う目的で作った。
 //DocumentSnapshotは、DocumentReferenceから得られるスナップショットで、単一のドキュメントデータを持っています。
 
  static Goal fromFirestore(DocumentSnapshot<Map<String, dynamic>> doc) {
    //Firestoreのdocumentから全てのデータを取ってくる。
    final map = doc.data()!;
    //Goalの全てのデータをfromMapする。
    final goal = Goal.fromMap(map); // これで goal は作れる。けれども ref情報がない。
    // goal.ref = doc.reference; // こうしたいなあと思う。けれども finalだから更新できない。
    final goalWithRef = goal.copyWith(ref: doc.reference); // copyWithを使えば更新できる。
    // goalWithRef っていうのは ref情報をちゃんと持ってる Goal クラスになった。
    return goalWithRef;
  }

//ToMapメソッド:JSONからDartに変えるメソッドです。
  Map<String, dynamic> toMap() {
    // ignore: unnecessary_cast
    return {
      'title': this.title,
      'goal': this.goal,
      'time': this.time,
      'ref': this.ref,
    };
  }

//copyWith:特定のフィールドの値を入れ替えたい場合に使えるメソッドです。
  Goal copyWith({
    String? title,
    String? goal,
    String? time,
    String? place,
    DocumentReference? ref,
  }) {
    return Goal(
      title: title ?? this.title,
      goal: goal ?? this.goal,
      time: time ?? this.time,
      ref: ref ?? this.ref,
    );
  }
}

レポジトリの作成

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:habituation_coationg_app/firestore_date/goal.dart';


/// ここでCRUD処理をまとめていきたい。

///get ref =>の書き方があまり馴染みがない。
/// 処理をしているわけではないので、関数のように書かなくてもよいからget refにした。
/// 中で重たい処理をするのなら、関数で書く必要がある。
/// getterにアクセスする場合は、重たい処理ではないことを明示するため。

class GoalRepository {
  /// UserのGoalデータを全権取得するメソッド
  ///
  
  //CollectionReferenceとは:コレクションやサブコレクションへの参照ができる。
 
  static CollectionReference<Map<String, dynamic>> get ref =>
      FirebaseFirestore.instance
          .collection('users')
          .doc('Ffn8a9Jya8gzazC7SCa0')
          .collection('goals');

  static Future<List<Goal>> fetchGoalList() async {
    ///現在のログインしているユーザのデータを取ってきたい。
    final user = FirebaseAuth.instance.currentUser;

    ///上記のままでは使えないので、.get()をして実体化させる。
    final snapshot = await ref.get();
    
    //QueryDocumentSnapshot型をList型に変更する。
    final list = snapshot.docs.map(Goal.fromFirestore).toList();
    return list;
  }

  //firebaseに値を追加する。
  static Future<void> addGoal(Goal goal) async {
    ///新しい追加されたuserの情報をtoMapとして持っている。
    ref.add(goal.toMap());
  }
}



Discussion