Firebaseについてあれこれ(Authentication, Cloud Firestore)

はじめに

 FirebaseのCloud Firestoreはバックエンドの実装を行うことなくデータベース管理ができるGoogleのサービスです。また、Authenticationは、誰でも簡単にアカウント認証やログイン機能を作ることができるサービスです。これらによってアプリケーション開発のハードルがぐんと下がります。  そんなおかげでプログラミング歴数ヶ月の素人でもwebアプリ開発ができたので(経験者からのアドバイスを多分に受けながらですが)、備忘録も兼ねて詰まったところなどを主に残そうと思います。

1. Authenticationでよくあるアカウント作成の流れを作る

Authenticationでアカウントを作成させる時、

  1. メールアドレスとパスワードを入力
  2. 認証用メールが入力したメールアドレスに届く
  3. 認証用URLを踏んで認証完了

がよくある会員登録制のアプリの基本的な動作ですが、Authenticationのメソッドには一発でそれを可能にするメソッドはありません(見つけられなかっただけかも)。そこで、メールとパスワードを入力すれば即座にアカウントが作成されるcreateUserWithEmailAndPasswordメソッドと、メールによって認証する機能を持つsendEmailVerificationメソッドの合わせ技で実装します。こんな感じです。

const handleSubmit = async (event: { preventDefault: () => any }) => {
    event.preventDefault();
    createUserWithEmailAndPassword(auth, email, password).then(() => {
      if (auth.currentUser !== null) {
        sendEmailVerification(auth.currentUser);
      }
      console.log(auth.currentUser);
    });
  };

これで上に書いたようなアカウント作成の流れが作れます。 auth.currentuserはユーザから見て自分のアカウントの情報を取得します。ここではメールアドレスやuidが入っています。 作成されたアカウントには、一位性のあるuidが発行され、紐づけられています。

2. Authenticationで作成したアカウントのuidをFirestoreのドキュメントIDと一致させたいとき

今回開発したアプリでは、アカウントを作成したら次はプロフィールを作成する流れになります。プロフィールは、Cloud Firestore上のデータベースに保存します。Firestoreのデータベースは、コレクション→ドキュメント→フィールド の順に階層構造になっています。コレクションはデータの大まかなジャンル(プロフィール、○○の履歴、△△の履歴)分け、ドキュメントはそのジャンルの中のデータの内容(プロフィールであれば名前、生年月日、職業とか)を指定し、フィールドに最終的に入力されたものを格納します。
ドキュメントには、ドキュメントIDという一意のIDが付きますが、これを自分で指定する方法と、自動生成IDに任せて付ける2通りの方法があります。プロフィールというドキュメントを作成する際、プロフィールはAuthenticationにあるアカウントと紐付かないといけません。なので、Authenticationのuidと、プロフィールのドキュメントIDを一致させるのが効果的です。そのためには、

  1. Authenticationからアカウントのuidを取得する
  2. 取得したuidをドキュメントIDとしてプロフィールを作成する

という流れが必要です。 コードにするとこうなります。

const handleCreate = async () => {
   // 入力フォームに空欄がないことを確かめる
    if (auth.currentUser !== null) {
      if (
        UserName !== "" &&
        UserNameKana !== "" &&
        UserTel !== "" &&
        UserPlan !== "" &&
        UserAdmin === false
      ) {
   // AuthenticationのuidをドキュメントIDとしてプロフィールを作成
        await setDoc(doc(db, "users", auth.currentUser.uid), {
          userName: UserName,
          userNameKana: UserNameKana,
          tel: UserTel,
          plan: UserPlan,
          admin: UserAdmin,
          addProfile: addProfile,
        });
        alert("追加できました");
      } else {
        alert("全ての欄を記入、選択してください。");
      }
    }
  };

これで一応プロフィールを作成することができます。(カナ名とかをカナ指定する処理などは未実装なので不完全ですが。。。)

次回は、

onAuthStateChangedについて説明します。(なんだそれ!)