⚔️

withConverterなるものを使ってみた!

2022/07/30に公開

.doc(id)と書けない?

FlutterFireのドキュメントを見て、最近流行りのFirebasewithConverterなるもので、uidを使って、特定のuserコレクションのデータを取得するプログラムを作ろうとしていたが、中々うまくいかなかった😱
こちらのドキュメントを参考にしながら、Freezedを使ったら、うまくいった気がする。

Freezedを使ったときは、toJSONやfromJSONを自動生成してくれて便利なのですが、そのままだと、withConverterで使えなかった🤔
ドキュメントをよくみるとfactoryコンストラクターがついたコードを追加していないからなのに気づいた!

Freezedを使うときは、普通にモデルを書いている時の、factoryコンストラクターも追加する!
今回だとこれを追加しないとエラーが出た!

fromFirestore
toFirestore

こちらが完成品です。参考までにどうぞ😅

Flutter3.0.3で作成

https://github.com/sakurakotubaki/withconverter-sample

Firebaseの設定は、Firebase CLIを使ってiOSとAndroidの開発環境を構築

  • FirebaseAuthenticationは、email,passwordを使用
  • FireStoreは、usersコレクションのデータを保存するのに使用

フォルダ構成はこんな感じ

今回は凄いもの作ってないですが、ファイルが多い!

modelフォルダにFreezedで使うファイルを作る。
repositoryフォルダに、FireStoreのusersコレクション値の取得するwithConverterを書く。

Freezedについては、こちらの記事を参考にしました!
自動生成するコマンドも種類があるみたいですね。
https://zenn.dev/sakusin/articles/b19e9a2c3829e0

Frezedの注意点!

2番目に自動生成されたファイルでエラー表示が出た?
エディターの機能を使えば解決した?

user_data.dart

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:flutter/foundation.dart';

part 'user_data.freezed.dart'; // ファイルと同じ名前にする(user_data)
part 'user_data.g.dart'; // ファイルと同じ名前にする(user_data)


class UserModel with _$UserModel {
  const factory UserModel({
    required String uid,
    required String name,
    required String email,
  }) = _UserModel;

  factory UserModel.fromJson(Map<String, dynamic> json) =>
      _$UserModelFromJson(json);

  factory UserModel.fromFirestore(
      DocumentSnapshot<Map<String, dynamic>> snapshot,
      SnapshotOptions? options,
      ) {
    final data = snapshot.data();
    return UserModel(
      uid: data?['uid'],
      name: data?['name'],
      email: data?['email'],
    );
  }

  Map<String, dynamic> toFirestore() {
    return {
      if (uid != null) "uid": uid,
      if (name != null) "name": name,
      if (email != null) "email": email,
    };
  }
}

repositoryフォルダのファイル

import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:withconverter_app/model/user_data.dart';

void getUser() async {
  // uidを取得する設定
  final user = FirebaseAuth.instance.currentUser;
  final uid = user?.uid;
  // 下のコードでuidを使えるようになる
  final ref = await FirebaseFirestore.instance
      .collection("users")
      .doc(uid)
      .withConverter(
        fromFirestore: UserModel.fromFirestore,
        toFirestore: (UserModel user, _) => user.toFirestore(),
      );
  final docSnap = await ref.get();
  final userRef = docSnap.data();
  if (user != null) {
    print('FireStoreから値を取得✋✋✋✋✋');
    print(user);
  } else {
    print("usersコレクションの取得に失敗しました!.");
  }
}

スクリーンショット

これで治った?

参考にしたFirebaseの公式ドキュメント
https://firebase.google.com/docs/firestore/query-data/get-data?hl=ja#dart

コードはGithubのソースコードを参考にしてください。 以前作成したプログラムに機能を追加しただけです。

今回は値を取得してデバッグするだけ

新規登録をした後にログインをしてみる。

やってみた感想

どうやら、無事にデータを取得できたようですね。使い方がよくわからなくて困っていて、どうやって理解したかというと、公式ドキュメントを読み続けた!
Freezedで使うときは、全てのコードは自動生成されないので、追加する必要がある。
やったことは、ドキュメントのコードを追加しただけ!

Discussion