FirebaseAuthでのユーザー登録時、HASURAにもFirebase側のUIDを保存する

webアプリケーションでのユーザー認証をFirebaseAuthenticationを行い、JWT認証でHASURAとデータ連携するつくりにしています。

「新規ユーザー登録をする際にFIrebaseAuthにも新規登録しつつ、HASURA側にもFIrebaseのUIDを保存して新規のレコードを追加する」という実装を試したのでメモしておきます。

コンポーネント(新規サインアップのフォーム)

必要な箇所だけ書いています。

export const Auth = () => {
  const user = firebase.auth().currentUser
  const {
    authUser,
  } = useFirebaseAuth() //FirebaseAuthでLoginやSignupするカスタムフック
  return (
    <>
      <form
        onSubmit={authUser}
        className="mt-8 flex justify-center items-center flex-col"
      >

        /* ここにemeilやpasswordのinput */

        <button
          type="submit"
        >
          Singup
        </button>
      </form>
    </>
  )
}

Signupボタンを押すと認証用のカスタムフックからauthUserが実行されます。

FirebaseAuth新規登録カスタムフック(authUser)

コンポーネントで実行されたauthUserが何をしているか確認。上記とは別ファイルのカスタムフック内の一部を抜粋。

const authUser = useCallback(
    async (e: FormEvent<HTMLFormElement>) => {
      e.preventDefault()
      if (isLogin) {
        //ログインフォームから来たときはsignInWithEmailAndPassword
        try {
          await firebase.auth().signInWithEmailAndPassword(email, password)
        } catch (e) {
          alert(e.message)
        }
        resetInput()
      } else {
                //新規登録フォームから来たときはcreateUserWithEmailAndPassword
        try {
          await firebase
            .auth()
            .createUserWithEmailAndPassword(email, password)
            .then((userCredential) => {
              //userCredentialから今新規登録したユーザの情報が取れる
              const param = {
                firebase_id: userCredential.user.uid,
                email: userCredential.user.email,
              }
              //ミューテーション用のフックで用意していた'createUserMutation'に必要なパラメータを渡してリクエスト
              createUserMutation.mutate(param)
            })
        } catch (e) {
          alert(e.message)
        }
        resetInput()
      }
    },
    [email, password, isLogin]
  )

FirebaseのAPI createUserWithEmailAndPassword を実行。ここでフォームで入力してもらったメールアドレスとパスワードを使う。

.thenすると userCredential というたったいま登録したユーザーの情報が返ってくる。
ここからUIDとメールアドレスを引っ張り出すことが出来ます。

UIDとメールアドレスを使って次はHASURAでユーザーをINSERTするクエリをやっていきます。
そのために別途用意していた createUserMutation は ReactQueryで CREATE_USER というユーザーを新規追加する用の関数です。

HASURA新規登録カスタムフック(createUserMutation)

必要な部分だけ抜粋

import { useEffect } from 'react'
import { useQueryClient, useMutation } from 'react-query'
import { GraphQLClient } from 'graphql-request'
import Cookie from 'universal-cookie'
import {CREATE_USER} from '../queries/queries' //mutationクエリ「CREATE_USER」をqueriesに作っておく
import {CreateUser } from '../types/types' //型も作っておく
import { useDispatch } from 'react-redux'
import { resetEditedTask, resetEditedNews } from '../slices/uiSlice'

const cookie = new Cookie()
let graphQLClient: GraphQLClient

export const useAppMutate = () => {
  const queryClient = useQueryClient()

  const createUserMutation = useMutation(
    (createUser: CreateUser) => graphQLClient.request(CREATE_USER, createUser),
    {
      onSuccess: (res) => {
        console.log(res)
      },
      onError: () => {
        dispatch(resetEditedTask())
      },
    }
  )

  return {
    createUserMutation,
  }
}

ReactQueryの「useMutation」を使い、さらにその中でリクエストを投げる用の graphql-request も使ってCREATE_USERを叩く。そのときにさっきFirebaseからかえってきたユーザーの情報のオブジェクトを、createUserというパラメータにまとめて渡すでOK。

mutationの CREATE_USER はクエリのファイルに作っておき、型も用意しておきましょう。

ReactQueryに慣れていきたい

ReactQuery自体はまだ分からないことが多いが、とりあえずこれで動く。

今回はこれまで。ではまた!