katekichiのゆるブログ

普段の作業メモや日常の出来事とか

「Electronではじめるアプリ開発」を写経してみた ⑤

諸々立て込んでいて停滞していた写経再開しました。今回は、Firebaseの設定から実装します。

firebase.google.com

目次:

Firebaseのセットアップ

上記のサイトでアカウント生成等をして取得した接続情報 を src/render

er/app.jsに貼ります。

import React from "react";
import { render } from "react-dom";
import { Router, Route, hashHistory } from "react-router";
import Login from "./Login";
import Signup from "./Signup";
import Rooms from "./Rooms";
import Room from "./Room";

import firebase from "firebase/firebase-browser";

const appRouting = (
    <Router history={hashHistory}>
        <Route path="/">
            <Route path="login" component={Login} />
            <Route path="signup" component={Signup} />
            <Route path="rooms" component={Rooms}>
                <Route path=":roomId" component={Room} />
            </Route>            
        </Route>
    </Router>
);

if (!location.hash.length) {
    location.hash = "#/login";
}

// Firebaseの初期化 ←ココ追加
var config = {
    apiKey: "xxxxxxx",
    authDomain: "electron-chat-cyyyyyy.firebaseapp.com",
    databaseURL: "https://electron-chat-cyyyyyy.firebaseio.com",
    projectId: "electron-chat-cyyyyyy",
    storageBucket: "electron-chat-cyyyyyy.appspot.com",
    messagingSenderId: "xxxxxxxx"
};
firebase.initializeApp(config);

render(appRouting, document.getElementById("app"));

ログイン画面の実装

src/renderer/Login.jsxにゴリゴリ実装します。 Validationはもう少し後々、工夫できそうです

import React from "react";
import { Link, hashHistory } from "react-router";
import Errors from "./Errors";
import firebase from "firebase/firebase-browser";

const FORM_STYLE = {
    margin: "0, auto",    
    padding: 30
};

const SIGNUP_LINK_STYLE = {
    display: "inline-block",    
    marginLeft: 10
};

export default class Login extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            email: localStorage.userEmail || "",
            password: localStorage.userPassword || "",
            errors: []
        };

        this.handleOnChangeEmail = this.handleOnChangeEmail.bind(this);
        this.handleOnChangePassword = this.handleOnChangePassword.bind(this);
        this.handleOnSubmit = this.handleOnSubmit.bind(this);        
    }

    handleOnChangeEmail(e) {
        this.setState({ email: e.target.value });
    }

    handleOnChangePassword(e) {
        this.setState({ password: e.target.value });
    }

    handleOnSubmit(e) {
        const { email, password } = this.state;
        const errors = [];
        let isValid = true;
        e.preventDefault();

        if (!email.length) {
            isValid = false;
            errors.push("Email address can't be blank.");
        }

        if (!password.length) {
            isValid = false;
            errors.push("Password can't be blank.");
        }

        if (!isValid) {
            this.setState({ errors });
            return;
        }

        firebase.auth().signInWithEmailAndPassword(email, password).then(() => {
            localStorage.userEmail = email;
            localStorage.userPassword = password;
            hashHistory.push("/rooms");            
        }).catch(() => {
            this.setState({ errors: ["Incorrect email or password."] });
        });
    }

    render() {
        return (
            <form style={FORM_STYLE} onSubmit={this.handleOnSubmit}>
                <Errors errorMessages={this.state.errors} />
                <div className="form-group">
                    <label>Email address*</label>
                    <input 
                        type="email"
                        className="form-control"
                        placeholder="email"
                        value={this.state.email}
                        onChange={this.handleOnChangeEmail}
                    />
                </div>
                <div className="form-group">
                    <label>Password</label>
                    <input 
                        type="password"
                        className="form-control"
                        placeholder="password"
                        value={this.state.password}
                        onChange={this.handleOnChangePassword}
                    />
                </div>

                <div className="form-group">
                    <button className="btn btn-large btn-default">Login</button>
                    <div style={SIGNUP_LINK_STYLE}>
                        <Link to="/signup">create new account</Link>
                    </div>
                </div>
            </form>
        );
    }
}

実行するとこんな感じになりました。

f:id:katekichi:20170525162743p:plain

サインアップ画面の実装

import React from "react";
import { Link, hashHistory } from "react-router";
import Errors from "./Errors";
import firebase from "firebase/firebase-browser";

const SIGNUP_FORM_STYLE = {
    margin: "0, auto",    
    padding: 30
};

const CANCEL_BUTTON_STYLE = {
    marginLeft: 10
};

export default class Login extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            email: "",
            password: "",
            name: "",
            photoURL: "",
            errors: []
        };

        this.handleOnChangeEmail = this.handleOnChangeEmail.bind(this);
        this.handleOnChangePassword = this.handleOnChangePassword.bind(this);
        this.handleOnChangeName = this.handleOnChangeName.bind(this);
        this.handleOnChangePhotoURL = this.handleOnChangePhotoURL.bind(this);
        this.handleOnSubmit = this.handleOnSubmit.bind(this);        
    }

    handleOnChangeEmail(e) {
        this.setState({ email: e.target.value });
    }

    handleOnChangePassword(e) {
        this.setState({ password: e.target.value });
    }

    handleOnChangeName(e) {
        this.setState({ name: e.target.value });
    }

    handleOnChangePhotoURL(e) {
        this.setState({ photoURL: e.target.value });
    }


    handleOnSubmit(e) {
        const { email, password, name, photoURL } = this.state;
        const errors = [];
        let isValid = true;
        e.preventDefault();

        if (!email.length) {
            isValid = false;
            errors.push("Email address can't be blank.");
        }

        if (!password.length) {
            isValid = false;
            errors.push("Password can't be blank.");
        }
        
        if (!name.length) {
            isValid = false;
            errors.push("Name can't be blank.");
        }

        if (!isValid) {
            this.setState({ errors });
            return;
        }

        firebase.auth().createUserWithEmailAndPassword(email, password).then(newUser => {
            return newUser.updateProfile({
                displayName: name,
                photoURL
            });
        }).then(() => {
            hashHistory.push("/rooms");
        }).catch(err => {
            this.setState({ errors: [err.message] });
        });
    }

    render() {
        return (
            <form style={SIGNUP_FORM_STYLE} onSubmit={this.handleOnSubmit}>
                <Errors errorMessages={this.state.errors} />
                <div className="form-group">
                    <label>Email address*</label>
                    <input 
                        type="email"
                        className="form-control"
                        placeholder="email"
                        value={this.state.email}
                        onChange={this.handleOnChangeEmail}
                    />
                </div>
                <div className="form-group">
                    <label>Password</label>
                    <input 
                        type="password"
                        className="form-control"
                        placeholder="password"
                        value={this.state.password}
                        onChange={this.handleOnChangePassword}
                    />
                </div>
                <div className="form-group">
                    <label>User name*</label>
                    <input 
                        type="text"
                        className="form-control"
                        placeholder="user name"
                        value={this.state.name}
                        onChange={this.handleOnChangeName}
                    />
                </div>
                <div className="form-group">
                    <label>Photo URL</label>
                    <input 
                        type="text"
                        className="form-control"
                        placeholder="photo URL"
                        value={this.state.photoURL}
                        onChange={this.handleOnChangePhotoURL}
                    />
                </div>

                <div className="form-group">
                    <button className="btn btn-large btn-primary">Create new account</button>
                    <Link to="/login">
                        <button type="button" style={CANCEL_BUTTON_STYLE} className="btn btn-large btn-default">Cancel</button>                
                    </Link>                    
                </div>
            </form>

        );
    }
}

f:id:katekichi:20170525163230p:plain

ユーザ作成を実際に作成するとFirebase上にユーザが作られました。

f:id:katekichi:20170525163525p:plain

今回は、ここまで!!

Reactビギナーズガイド ―コンポーネントベースのフロントエンド開発入門

Reactビギナーズガイド ―コンポーネントベースのフロントエンド開発入門

入門 React ―コンポーネントベースのWebフロントエンド開発

入門 React ―コンポーネントベースのWebフロントエンド開発