Firebase Auth react
やfirebase react
で検索すると、基本的なemail+passwordでユーザー登録する機能の作り方
は出くるのですが、ユーザー名も一緒に登録する方法を調べていても一向にしっくりくる情報が得られないんですよね。。
そこで、この記事ではfirebase+reactでユーザー登録の機能を作る際に、ユーザー名もセットで登録する方法
について解説します。
実装の全体像
まずは全体像を掴みましょう。
firebaseでユーザー登録
といえば、Authenticationですよね。以下の画像のように、様々な認証方法があってとても便利な機能です。
ただ、初心者の僕はここで疑問が浮かびます。
「Authenticationでメールアドレスとパスワード、ユーザーのIdが管理できるのはわかった。だけど、ユーザー名を登録したいと思ったらどうすれば良いんだろう?🤔」
僕はこの疑問についてずっと考えたのですが、良い答えに辿り着けず数日が経過したある日、ふと思いました。
「もしかしたら、Firestore使えばいけるんじゃね?」
そうです。firebaseでユーザー名を登録する場合はAuthenticationではなくfirestoreにデータを保存する必要があったのです。
このAuthenticationでどうすればユーザー名登録できるか
みたいな考えに束縛されて、答えに辿り着けずにいました。
具体的にどうすれば良いのか
前述の通り、firestore
にdb.collection('users').doc(uid).set(userInitialData)
を使ってusername
、email
、password
のデータを保存します。(後述します)
ユーザーを追加する方法を解説
仮に、email
とpassword
だけでユーザー登録するとしたら、特にfirestoreを使う必要はなく、createUserWithEmailAndPassword
でできるのですが、ユーザー名(username)
を登録するとなると、firestoreを使う必要があります。
まずは、お好みの形でFormを作成してください。
僕の場合は、Bootstrapを使っているので、SignUp.jsx
ファイルは以下のようになりました。
今回特にみて欲しいのはhundlesubmit
の部分です。
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の挙動を示す関数を記述します。
//省略しています
//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()
を定数化しています。
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
の中に入っているemail
、username
、uid
を取り出しました。
(createUserWithEmailAndPasswordはfirebaseの公式のリファレンス(英語)にメソッドの返り値や引数などの詳細が載っています。)
そして、firebase.firestore().collection('users').doc(uid).set(userInitialData)
でコレクションにデータを保存します。
繰り返しになりますが、users
というコレクションの、uid
をIDにもつドキュメントに、先ほど取得したuserInitialData
を.set()
メソッドで登録します。
これで完了です🙌🙌