Firebase Auth + React ログイン/登録/ログアウト

ReactでFirebase Authするメモ。`create-react-app`したところから。

```bash
$ npm install --save firebase react-router react-router-dom
```

## src/firebase.js
firebaseの設定。

```jsx
import firebase from "firebase";
export default firebase.initializeApp({
  // apiKeyとか
});
```

## src/components/App.js 
ログインしてたら`<Home>`。未ログインなら`<Login>`へ。
`Route render={}`のところをなんとかしたい。

```jsx
import React from 'react';
import { BrowserRouter, Route, Redirect } from "react-router-dom";
import Login from './Login';
import Home from './Home';
import firebase from '../firebase';

class App extends React.Component {

  constructor(props) {
    super(props);
    this.state = { loading: true, authenticated: false, user: null };
  }

  componentWillMount() {
    firebase.auth().onAuthStateChanged(user => {
      if (user) {
        this.setState({
          authenticated: true,
          currentUser: user,
          loading: false
        });
      } else {
        this.setState({
          authenticated: false,
          currentUser: null,
          loading: false
        });
      }
    });
  }

  render() {
    const { authenticated, loading } = this.state;
    if (loading) return <p>loading..</p>;
    return (
      <BrowserRouter>
        <div>
          <Route
            exact
            path="/"
            render={() =>
              authenticated === true ? (
                <Home />
              ) : (
                <Redirect to="/login" />
              )
            }
          />
          <Route
            exact
            path="/login"
            render={() =>
              authenticated === false ? (
                <Login />
              ) : (
                <Redirect to="/" />
              )
            }
          />
        </div>
      </BrowserRouter>
    );
  }
};


export default App;
```

## src/components/Login.js (登録とログイン)

Loginとsignupは同じコンポーネントを使う。

```jsx
import React from 'react';
import { withRouter } from "react-router";
import firebase from '../firebase';

class Login extends React.Component {
  constructor(props) {
    super(props);
    this.state = { email: '', password: '' };
    this.handleSignUp = this.handleSignUp.bind(this);
    this.handleLogin = this.handleLogin.bind(this);
  }
  async handleSignUp(e) {
    e.preventDefault();
    const { email, password } = this.state;
    try {
      await firebase.auth().createUserWithEmailAndPassword(email, password);
      this.props.history.push('/');
    } catch (error) {
      alert(error);
    }
  }
  async handleLogin(e) {
    e.preventDefault();
    const { email, password } = this.state;
    try {
      await firebase.auth().signInWithEmailAndPassword(email, password);
      this.props.history.push('/');
    } catch (error) {
      alert(error);
    }
  }
  render() {
    const { email, password } = this.state;
    return (
      <div>
        <div>
          <label htmlFor="email">Email</label>
          <input id="email" value={email} type="text" onChange={ (e) => this.setState({ email: e.target.value }) } />
        </div>
        <div>
          <label htmlFor="password">password</label>
          <input id="password" value={password} type="password" onChange={ (e) => this.setState({ password: e.target.value }) } />
        </div>
        <button onClick={this.handleSignUp}>Sign up</button>
        <button onClick={this.handleLogin}>Login</button>
      </div>
    );
  }
};
export default withRouter(Login);
```

## src/components/Home.js (ログアウト)
```jsx
import React from 'react';
import firebase from '../firebase';

const Home = () => (
  <div>
    Home
    <button onClick={ () => firebase.auth().signOut() }>sign out</button>
  </div>
);

export default Home;
```