react

ReactとFirebaseを使ってログインフォームを実装する③

ログイン機能を確認するため、先にEメールとパスワードでのログインを完了させます。その次にダイアログ表示まで実装します。

FirebaseでEメールとパスワードでのログイン設定

FIrebaseのコンソール画面の左側にあるAuthenticationをクリックします。ログイン方法からメール/パスワードをクリックして有効にするをオンにして保存しましょう。

FIrebaseのコンソール画面

これだけでEメールとパスワードでのログインできます。簡単です。

ログインフォームをダイアログ表示にする

material-uiのダイアログを使用します。ダイアログを管理するステートを用意し、trueの時はダイアログ表示、falseで閉じます。

下記のURLを参照してください。
https://material-ui.com/components/dialogs/

NavBarを編集しましょう。Reduxのstoreからログイン情報を取得して、ログインとログアウト処理を切り替えています。LoginFormにformTextを渡すことでログインとサインアップも切り替えてます。

firebase.auth().signOut()でログアウトできます。 コメントを参照してください。

import React, { useState, Fragment } from 'react';
import { connect } from 'react-redux';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import { makeStyles } from '@material-ui/core/styles';
import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
import Dialog from '@material-ui/core/Dialog';
import DialogContent from '@material-ui/core/DialogContent';
import DialogTitle from '@material-ui/core/DialogTitle';

import firebase from '../config/firebase';
import LoginForm from './LoginForm';

const useStyles = makeStyles(theme => ({
  root: {
    flexGrow: 1,
  },
  title: {
    flexGrow: 1,
  },
}));

function NavBar(props) {
  const classes = useStyles();
  // ダイアログ表示のステート
  const [daialogOpen, setDaialogOpen] = useState(false);
  // ログインとサインアップを切り替えるステート
  const [formText, setFormText] = useState('ログイン');

  const handleClickSignUpOpen = () => {
    // ダイアログ表示してformTextを新規登録にする
    setDaialogOpen(true);
    setFormText('新規登録');
  };
  const handleClickLoginOpen = () => {
    // ダイアログ表示してformTextをログインにする
    setDaialogOpen(true);
    setFormText('ログイン');
  };

  const handleClose = () => {
    // ダイアログを閉じる
    setDaialogOpen(false);
  };

  const logout = () => {
    // firebaseからのログアウト処理
    firebase
      .auth()
      .signOut()
      .then(() => {
        console.log('ログアウトしました');
      })
      .catch(error => {
        console.log(`ログアウト時にエラーが発生しました (${error})`);
      });
  };

  const onFormTextSignUp = () => {
    setFormText('新規登録');
  };

  const onFormTextLogin = () => {
    setFormText('ログイン');
  };

  const renderSwitchLoginOrSignUp = () => {
    // ログインフォームの下にログインとサインアップを切り替える処理
    if (formText === 'ログイン') {
      return (
        <div style={{ textAlign: 'center', margin: 20 }}>
          アカウントをお持ちでないですか?
          <span onClick={onFormTextSignUp} style={{ color: 'rgb(0, 112, 210)', cursor: 'pointer' }}>
            新規登録
          </span>
        </div>
      );
    } else {
      return (
        <div style={{ textAlign: 'center', margin: 20 }}>
          すでにアカウントをお持ちですか?
          <span onClick={onFormTextLogin} style={{ color: 'rgb(0, 112, 210)', cursor: 'pointer' }}>
            ログイン
          </span>
        </div>
      );
    }
  };

  const renderDialog = () => {
    // ログアウト時、ログインフォームをダイアログ表示するボタン配置
    return (
      <Fragment>
        <div>
          <Button color="inherit" onClick={handleClickLoginOpen}>
            ログイン
          </Button>
        </div>
        <div>
          <Button color="inherit" onClick={handleClickSignUpOpen}>
            無料登録
          </Button>
        </div>
        <Dialog open={daialogOpen} onClose={handleClose} fullWidth maxWidth={'sm'}>
          <DialogTitle className={classes.dialogTitle}>{formText} </DialogTitle>
          <DialogContent>
            <LoginForm formText={formText} />
            {renderSwitchLoginOrSignUp()}
          </DialogContent>
        </Dialog>
      </Fragment>
    );
  };

  const renderLogout = () => {
    // ログインしてたら表示、ログアウトボタン
    return (
      <Button
        color="inherit"
        onClick={() => {
          logout();
          handleClose();
        }}
      >
        ログアウト
      </Button>
    );
  };

  const renderAuth = () => {
    if (props.isLoggedIn) {
      // ログインしていたらログアウトボタン表示
      return renderLogout();
    } else {
      // ログアウトしていたらログインボタン表示
      return renderDialog();
    }
  };

  return (
    <AppBar position="static">
      <Toolbar>
        <Typography variant="h6" className={classes.title}>
          News
        </Typography>
        {renderAuth()}
      </Toolbar>
    </AppBar>
  );
}

const mapStateToProps = state => {
  return {
    isLoggedIn: state.auth.isLoggedIn,
  };
};

export default connect(mapStateToProps)(NavBar);

ログインフォームはダイアログで表示するのでLandingPage.jsxのLoginFormコンポーネントは削除しましょう。そしてログイン状態ならLoginedPageにリダイレクトするようにします。

import React from 'react';
import { connect } from 'react-redux';
import { Redirect } from 'react-router-dom';

function LandingPage(props) {
  if (props.isLoggedIn) {
    return <Redirect to={'/logined'} />;
  } else {
    return <div>LandingPage</div>;
  }
}

const mapStateToProps = state => {
  return { isLoggedIn: state.auth.isLoggedIn };
};

export default connect(mapStateToProps)(LandingPage);

ここで挙動を確認してみましょう。ローカルサーバー起動します。

ヘッダーのログイン、新規登録ボタンでダイアログが表示されます。test@gmail.comなどの適当なEメールとパスワードで登録すると、ページが偏移してLoginedPageになります。

ログアウトをクリックしてLandingPageになっていたら正しく動作しています。

LandingPageになっていたら正しく動作

FirebaseのコンソールでAuthenticationを確認するとユーザーが登録されています!

Authenticationを確認

おわり

お疲れさまでした!ほぼ完成です。あとはソーシャルログインを実装するためにfirebaseにそれぞれのプロバイダーapiキーなどを登録するだけです。

今回はダイアログの表示とログイン状態による表示の切り替えが主でした。material-uiを使えば簡単に実装できます。次回でログインフォームは完成です。

連載記事(全4回)

Sponsored Link

-react