18
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Firebase+Reactで会員登録機能を作る際に、ユーザー名(username)も一緒に登録したい!

Posted at

Firebase Auth reactfirebase reactで検索すると、基本的なemail+passwordでユーザー登録する機能の作り方は出くるのですが、ユーザー名も一緒に登録する方法を調べていても一向にしっくりくる情報が得られないんですよね。。

そこで、この記事ではfirebase+reactでユーザー登録の機能を作る際に、ユーザー名もセットで登録する方法について解説します。

実装の全体像

まずは全体像を掴みましょう。

firebaseでユーザー登録といえば、Authenticationですよね。以下の画像のように、様々な認証方法があってとても便利な機能です。
スクリーンショット 2020-11-03 21.46.29.png

スクリーンショット 2020-11-03 21.49.04.png

ただ、初心者の僕はここで疑問が浮かびます。

「Authenticationでメールアドレスとパスワード、ユーザーのIdが管理できるのはわかった。だけど、ユーザー名を登録したいと思ったらどうすれば良いんだろう?🤔」

僕はこの疑問についてずっと考えたのですが、良い答えに辿り着けず数日が経過したある日、ふと思いました。

「もしかしたら、Firestore使えばいけるんじゃね?」

そうです。firebaseでユーザー名を登録する場合はAuthenticationではなくfirestoreにデータを保存する必要があったのです。

このAuthenticationでどうすればユーザー名登録できるかみたいな考えに束縛されて、答えに辿り着けずにいました。

具体的にどうすれば良いのか

前述の通り、firestoredb.collection('users').doc(uid).set(userInitialData)を使ってusernameemailpasswordのデータを保存します。(後述します)

ユーザーを追加する方法を解説

仮に、emailpasswordだけでユーザー登録するとしたら、特にfirestoreを使う必要はなく、createUserWithEmailAndPasswordでできるのですが、ユーザー名(username)を登録するとなると、firestoreを使う必要があります。

まずは、お好みの形でFormを作成してください。

僕の場合は、Bootstrapを使っているので、SignUp.jsxファイルは以下のようになりました。
今回特にみて欲しいのはhundlesubmitの部分です。

SignUp.jsx
import React, { useRef, useState } from "react"
import { Form, Button, Card, Alert } from "react-bootstrap"
import { useAuth } from "../contexts/AuthContext"
import { Link, useHistory } from "react-router-dom"

export default function Signup() {
 // ※長くなりすぎるので、一部省略しています
  const [error, setError] = useState("")
  const [loading, setLoading] = useState(false)
  const history = useHistory()

//特にみて欲しいのはここ
  async function handleSubmit(e) {
    e.preventDefault()

    //パスワードの一致値チェック
    if (passwordRef.current.value !== passwordConfirmRef.current.value) {
      return setError("パスワードが一致しません")
    }

  //fromで送られてきた値を処理する
    try {
      setError("")
      setLoading(true)
    //signUpという別のコンポーネントに記述した関数に引数として、fromの値を渡し、実行させる
      await signup( usernameRef.current.value, emailRef.current.value, passwordRef.current.value)
      history.push("/")
    } catch {
      setError("アカウントの作成に失敗しました")
    }

    setLoading(false)
  }

  return (
    <>
      <Card>
        <Card.Body>
          <h2 className="text-center mb-4">サインアップ</h2>
          {error && <Alert variant="danger">{error}</Alert>}
          <Form onSubmit={handleSubmit}>
            <Form.Group id="username">
              <Form.Label>名前</Form.Label>
              <Form.Control type="text" ref={usernameRef} required />
            </Form.Group>
            <Form.Group id="email">
              <Form.Label>Email</Form.Label>
              <Form.Control type="email" ref={emailRef} required />
            </Form.Group>
            <Form.Group id="password">
              <Form.Label>パスワード</Form.Label>
              <Form.Control type="password" ref={passwordRef} required />
            </Form.Group>
            <Form.Group id="password-confirm">
              <Form.Label>パスワードの確認</Form.Label>
              <Form.Control type="password" ref={passwordConfirmRef} required />
            </Form.Group>
            <Button disabled={loading} className="w-100" type="submit">
              登録する
            </Button>
          </Form>
        </Card.Body>
      </Card>
    </>
  )
}

以下のファイルにSignUpの挙動を示す関数を記述します。

AuthContext.jsx
//省略しています  

 //formが値を送信するとこのSignUp関数が実行される
  function signup(username, email, password) {
    //createUserWithEmailAndPassword(これはfirebaseのメソッド)でユーザーを作成
    return auth.createUserWithEmailAndPassword(email, password)
    //ユーザーを作成したら
      .then(result => {
     //userが戻り値として返ってくるので、それをuserに代入
        const user = result.user
     //userに値が入っていれば
        if(user) {
          //userの中にあるuidをuidに代入
          const uid = user.uid
          //他にも持っている値でfirestoreに登録したいものをuserInitialDataに代入
          const userInitialData = {
            email: email,
            uid: uid,
            username: username
          }

       //firestoreのusersというコレクションに、uidをドキュメントIDとしてもつ、 userInitialDataを登録する
       firebase.firestore().collection('users').doc(uid).set(userInitialData)
            .then('ユーザーが作成されました!')
        }
      })
  }

//以下省略

auth.createUserWithEmailAndPassword(email, password)のauthはfirebaseの初期設定ファイルで、app.auth()を定数化しています。

firebase.jsx

const app = firebase.initializeApp({
  apiKey: process.env.REACT_APP_FIREBASE_API_KEY,
  authDomain: process.env.REACT_APP_FIREBASE_AUTH_DOMAIN,
  databaseURL: process.env.REACT_APP_FIREBASE_DATABASE_URL,
  projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
  storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.REACT_APP_FIREBASE_MESSAGING_SENDER_ID,
  appId: process.env.REACT_APP_FIREBASE_APP_ID
})

export const auth = app.auth()
export default app

ちなみに、appの部分は直接このファイルに書き込むのではなく、別に用意した.envファイルに記述して、.gitignoreしています。

その方法はこちらの記事で説明しています。

AuthContext.jsxで使っているcreateUserWithEmailAndPasswordメソッドは戻り値がPromise < UserCredential >となっています。UserCredentialはemailやuidなど、他にも様々なデータを格納しています。

今回は、そこからuserの中に入っているemailusernameuidを取り出しました。

(createUserWithEmailAndPasswordはfirebaseの公式のリファレンス(英語)にメソッドの返り値や引数などの詳細が載っています。)

そして、firebase.firestore().collection('users').doc(uid).set(userInitialData)でコレクションにデータを保存します。
繰り返しになりますが、usersというコレクションの、uidをIDにもつドキュメントに、先ほど取得したuserInitialData.set()メソッドで登録します。

これで完了です🙌🙌

参考

Firebase API Reference

18
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?