withConverterなるものを使ってみた!
.doc(id)と書けない?
FlutterFireのドキュメントを見て、最近流行りのFirebasewithConverterなるもので、uidを使って、特定のuserコレクションのデータを取得するプログラムを作ろうとしていたが、中々うまくいかなかった😱
こちらのドキュメントを参考にしながら、Freezedを使ったら、うまくいった気がする。
Freezedを使ったときは、toJSONやfromJSONを自動生成してくれて便利なのですが、そのままだと、withConverterで使えなかった🤔
ドキュメントをよくみるとfactoryコンストラクターがついたコードを追加していないからなのに気づいた!
Freezedを使うときは、普通にモデルを書いている時の、factoryコンストラクターも追加する!
今回だとこれを追加しないとエラーが出た!
fromFirestore
toFirestore
こちらが完成品です。参考までにどうぞ😅
Flutter3.0.3で作成
Firebaseの設定は、Firebase CLIを使ってiOSとAndroidの開発環境を構築
- FirebaseAuthenticationは、email,passwordを使用
- FireStoreは、usersコレクションのデータを保存するのに使用
フォルダ構成はこんな感じ
今回は凄いもの作ってないですが、ファイルが多い!
modelフォルダにFreezedで使うファイルを作る。
repositoryフォルダに、FireStoreのusersコレクション値の取得するwithConverterを書く。
Freezedについては、こちらの記事を参考にしました!
自動生成するコマンドも種類があるみたいですね。
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の公式ドキュメント
コードはGithubのソースコードを参考にしてください。 以前作成したプログラムに機能を追加しただけです。
今回は値を取得してデバッグするだけ
新規登録をした後にログインをしてみる。
やってみた感想
どうやら、無事にデータを取得できたようですね。使い方がよくわからなくて困っていて、どうやって理解したかというと、公式ドキュメントを読み続けた!
Freezedで使うときは、全てのコードは自動生成されないので、追加する必要がある。
やったことは、ドキュメントのコードを追加しただけ!
Discussion