前回は、Firebase Authentication の機能を使って、ユーザーが認証されていない場合、ログイン画面へ遷移しました。

今回は、パスワード再設定機能を実装します。

まずは、useAuth.ts で、パスワード再設定のフックを作成します。

パスワード再設定するには、firebase/authsendPasswordResetEmailを使用します。

また、sendPasswordResetEmailの第一引数には、firebaseConfig.ts で設定したfireauth、第二引数には、emailを指定します。

export const usePasswordReset = () => {
  const passwordReset = (email: string) => {
    sendPasswordResetEmail(fireauth, email)
      .then(() => {})
      .catch(err => {
        console.log(err.message)
      })
  }

  return { passwordReset }
}

メールの送信が成功した場合と失敗した場合にメッセージを表示するようにします。

成功した場合は、ログイン画面へ遷移させます。

export const usePasswordReset = () => {
  const navigate = useNavigate()

  const [success, setSuccess] = useState(false)
  const [error, setError] = useState(null)

  const passwordReset = (email: string) => {
    sendPasswordResetEmail(fireauth, email)
      .then(() => {
        setSuccess(true)
        setTimeout(() => {
          navigate("/login")
        }, 2000)
      })
      .catch(err => {
        console.log(err.message)
        setError(err.message)
      })
  }

  return { success, error, passwordReset }
}

次に、パスワード再設定画面を作成します。

pages フォルダに PasswordReset.tsx を作成します。

import React, { useState } from "react"
import {
  Avatar,
  Alert,
  Button,
  CssBaseline,
  TextField,
  Box,
  Typography,
  Container,
  Grid,
  Link,
} from "@mui/material"
import LockOutlinedIcon from "@mui/icons-material/LockOutlined"

export default function PasswordReset() {
  const [email, setEmail] = useState("")

  const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault()
  }

  return (
    <Container component="main" maxWidth="xs">
      <CssBaseline />
      <Box
        sx={{
          marginTop: 8,
          display: "flex",
          flexDirection: "column",
          alignItems: "center",
        }}
      >
        <Avatar sx={{ m: 1, bgcolor: "secondary.main" }}>
          <LockOutlinedIcon />
        </Avatar>
        <Typography component="h1" variant="h5">
          パスワード再設定
        </Typography>
        <Box component="form" onSubmit={handleSubmit} noValidate sx={{ mt: 1 }}>
          <TextField
            margin="normal"
            required
            fullWidth
            id="email"
            label="メールアドレス"
            name="email"
            autoComplete="email"
            autoFocus
            value={email}
            onChange={e => setEmail(e.target.value)}
          />
          <Button
            type="submit"
            fullWidth
            variant="contained"
            sx={{ mt: 3, mb: 2 }}
          >
            送信
          </Button>
          <Grid container sx={{ justifyContent: "center" }}>
            <Grid item>
              <Link href="login" variant="body2">
                戻る
              </Link>
            </Grid>
          </Grid>
        </Box>
      </Box>
      {error && (
        <Alert severity="error">メールアドレスに送信できませんでした</Alert>
      )}
      {success && (
        <Alert severity="success">メールアドレスに送信しました</Alert>
      )}
    </Container>
  )
}

usePasswordResetをインポートし、設定します。

const { success, error, passwordReset } = usePasswordReset()

データ送信後、passwordReset を使用しましょう。

const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
  event.preventDefault()
  passwordReset(email)
}

ログイン画面の『パスワードを忘れた方』をクリックすると、パスワード再設定画面へ遷移するようにします。

App.tsx へ移動し、Routeでパスワード再設定画面へ遷移できるようにします。

<Routes>
  <Route path="/" element={<Home />} />
  <Route path="login" element={<Login />} />
  <Route path="signup" element={<Signup />} />
  <Route path="password-reset" element={<PasswordReset />} />
</Routes>

Login.tsx へ移動し、リンクを繋げましょう。

<Grid item xs>
  <Link href="password-reset" variant="body2">
    パスワードを忘れた方
  </Link>
</Grid>

では、動作確認します。

image2

『パスワードを忘れた方』をクリックすると、

image3

パスワード再設定へ遷移しました。

異なるメールアドレスを入力し、送信ボタンをクリックしてみましょう。

image4

エラーメッセージが表示されました。

では、正しいメールアドレスを入力し、送信ボタンをクリックしてみましょう。

image5

image6

送信メッセージが表示され、ログイン画面へ遷移しました。

image7

メールボックスに再設定メールが届いていました。

次回は、Firestore Database からデータを取得し、ブラウザに表示させます。

ブログ一覧