React+Redux+Firebase Authenticationでログイン/ログアウト機能を実装する (2)

# 前回

前回の記事 [React+Redux+Firebase Authenticationでログイン/ログアウト機能を実装する (1)](http://qiita.com/k5trismegistus/items/2b82c9721e5d245b54ca) では前準備を行いました。

今回は、実際にログイン・ログアウトを行う機能を作成します。

# Action、Reducerの作成

まず、最初にログイン・ログアウト状態をReduxのステートで管理できるようにするためのActionとReducerを作成します。これらはReduxの話になってしまうのでコードをのせるだけにとどめて説明は省略します。

```actions/actions.js
export const LOGIN_OK = 'LOGIN_OK'
export const LOGOUT = 'LOGOUT'

export const loginOk = (user) => {
  return {
    type: LOGIN_OK,
    payload: {
      displayName: user.displayName,
      email: user.email,
      uid: user.uid
    }
  }
}

export const logOut = () => {
  return {
    type: LOGOUT
  }
}
```

```js:reducers/auth.js
const initialState = {
  uid: null,
  displayName: null,
  email: null
}

const auth = (state=initialState, action) => {
  switch (action.type) {
    case "LOGIN_OK": {
      return Object.assign({}, state, {
        uid: action.payload.uid,
        displayName: action.payload.displayName,
        email: action.payload.email
      })
    }

    case 'LOGOUT': {
      return Object.assign({}, state, {
        uid: null,
        displayName: null,
        email: null
      })
    }

    default: {
      return state
    }
  }
}

export default auth
```

# ログインコンポーネントの作成

ログインボタンを設置するAuthコンポーネントを作成します。

Firebaseは(今作ろうとしているReduxのステートとは無関係に)ログイン状態を管理しています。なので、コンポーネントがマウントされたタイミングでログイン状態だったら`LOGIN_OK`アクションを発行してReduxの世界でもログイン状態にします。ログアウト状態だった場合はログインボタンを押すとポップアップでログインダイアログを出します。

このコンポーネントはContainerの方を先に作成します。

## Container Component

`doLogin`がログインポップアップを表示するメソッド、`refLogin`がFirebaseのログイン状態が変化したらRedux世界のログインを行うメソッドです。`doLogin`はログインポップアップを出すのみで、ログイン処理はFirebaseと`refLogin`に丸投げしています。

```js:containers/AuthContainer.js
import firebase from 'firebase'
import { connect } from 'react-redux'
import Auth from '../components/Auth'
import { loginOk } from '../actions/auth'

const mapStateToProps = (state) => {
  return {
    isAuth: state.isAuth
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    doLogin: () => {
      let provider = new firebase.auth.GoogleAuthProvider()
      firebase.auth().signInWithPopup(provider)
    },
    refLogin: () => {
      firebase.auth().onAuthStateChanged(user => {
        if (!user) {
          return
        }
        dispatch(loginOk(user))
      })
    }
  }
}

const AuthContainer = connect(
  mapStateToProps,
  mapDispatchToProps
)(Auth)

export default AuthContainer
```

`firebase.auth().signInWithPopup`は名前の通りログインポップアップを表示するメソッド、`firebase.auth().onAuthStateChanged`は現在のログイン状態が変化したらユーザー情報を引数に取るコールバック関数を呼び出すメソッドです。

## Presentational Component

Presentational ComponentのほうはpropsにはいっているContainerから受け取ったメソッドを呼び出すだけ。

```js:components/Auth.jsx
import React, { Component } from 'react'

export default class Auth extends Component {

  constructor(props) {
    super(props)
  }

  componentDidMount() {
    this.props.refLogin()
  }

  render() {
    return (
      <div>
        <button onClick={this.props.doLogin}>Login</button>
      </div>
    )
  }
}
```

これでログイン機能は実現できました。ログアウトの方は同じような考え方でできるので省略いたします。

# もっと詳しく

- Firebaseライブラリの認証周りはこれだけ覚えていたらとりあえず使い始められます。
[Firebase Authentication これだけは覚えておけ！テストに出るぞ！](http://qiita.com/niusounds/items/829780bdc45d34b4d1e7)

- Firebaseの認証機能についてもっと知りたくなったら、公式サポートページをみましょう。  
[Firebase Authentication はじめに](https://firebase.google.com/docs/auth/?hl=ja)