FlutterでFirebaseAuthのSignup時にFirebaseFirestoreにユーザー情報を登録、Signin時にユーザー情報を取得する方法

FlutterでFirebaseAuthのSignup時にFirebaseFirestoreにユーザー情報を登録、Signin時にユーザー情報を取得する方法

1、Signup
・FirebaseAuthのcreateUserWithEmailAndPassword時にUserCredentialを取得
・UserCredentialからuidを取得
・FirebaseFirestoreにdocのuidを指定してユーザー情報をset();

```dart
ElevatedButton(
  child: const Text('新規登録'),
  onPressed: () async {
    try {
      if(nameController.text.isNotEmpty 
           && idController.text.isNotEmpty 
           && emailController.text.isNotEmpty 
           && passwordController.text.isNotEmpty) {
        UserCredential userCredential = await FirebaseAuth.instance.createUserWithEmailAndPassword(
          email: emailController.text,
          password: passwordController.text,
        );
        await FirebaseFirestore.instance.collection('users').doc(userCredential.user!.uid).set({
          'name': nameController.text,
          'id': idController.text,
          'email': emailController.text,
          'createdTime': Timestamp.now(),
          'updatedTime': Timestamp.now(),
        });
        Navigator.pop(context);
      }
    } catch(e) {
    print(e);
    }
  },
),         
```


2、Signin
・FirebaseAuthのsignInWithEmailAndPassword時にUserCredentialを取得
・UserCredentialからuidを取得
・FirebaseFirestoreのdocをuidを指定してユーザー情報をget();
・ユーザー情報からidを取得

```dart
ElevatedButton(
  child: const Text('ログイン'),
  onPressed: () async {
    try{
      UserCredential userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword(
        email: emailController.text,
        password: passwordController.text,
      );
      DocumentSnapshot documentSnapshot = await FirebaseFirestore.instance.collection('users').doc(userCredential.user!.uid).get();
      Map<String, dynamic> data = documentSnapshot.data() as Map<String, dynamic>;
      setState(() {
        id = data['id'];
        uid = userCredential.user!.uid;
        isLogined = true;
      });
      Navigator.pushNamed(context, '/');
    }catch(e) {
      print(e);
    }
  },
),
```

3、ユーザー検索
・FirebaseFirestoreのユーザーデータをwhere句を使って検索、QuerySnapshotを取得
・今回、ユニークキーとしてidを定義しているので必ず単数、docs[0]でアクセス
・ユーザー登録がない場合は別の処理へ（省略）

```dart
ElevatedButton(
  child: const Text('ID検索'),
  onPressed: () async {
    try{
      final QuerySnapshot<Map<String, dynamic>> querySnapshot = await FirebaseFirestore.instance.collection('users').where('id', isEqualTo: idController.text).get();
      if(querySnapshot != null) {
        setState(() {
          uid = querySnapshot.docs[0].id;
          name = querySnapshot.docs[0].data()['name'];
          isCreated = true;
        });
      } else {
        setState(() {
          isCreated = false;
        });
      }
    } catch(e) {
      print(e);
    }
  },
),
```

・当初はidとpwでAuthを自作したが、細かい例外のハンドリングの手作りが煩雑、ユーザーがpw忘れた際のpw再発行の連絡手段として結局メールアドレスは必要になることから、最初からメールアドレスとパスワードでAuth処理を行い、idはidで別の管理が良いという考えに至ったため、
・ただし、ユーザー認識のユニークキーがidとuidと2種類共存してしまうのは若干スマートではない気がするのでなんとかしたい
・Firebaseのデータ型、QuerySnapshot、DocumentSnapshot等の違いがしっかりわかっていない、いつもググりながらコピペと雰囲気で書いているのでクリアに理解したい
https://firebase.flutter.dev/docs/firestore/usage
https://qiita.com/takahi5/items/a07cc77f6f11c1bd973c
https://qiita.com/kabochapo/items/1ef39942ac1206c38b2d
https://www.wakuwakubank.com/posts/723-firebase-firestore-query