firebaseでカルタつくった話

おはようございます!こんばんは!

Tech KAYAC Advent Calendar 2017の9日目の記事をお届けします。
受託事業部でWebフロントエンドエンジニアをしております、新卒2年目のゆみこふ @yumikokh です。

はじめに

今年9月に開催されたHTML5CONFERENCE2017で、弊社のブースを出展させていただくことになり
展示作品の1つとして「フロントエンドあるあるカルタ」というものを制作しました。
そのときに使ったのがFirebase!
ほぼサーバーサイドの経験が0に等しいフロントエンドエンジニア(私)が、
簡易ではあるけどもオンライン通信ゲームを作ることができる!すごい!ということで
あるあるカルタの紹介とともにFirebaseの始め方について書こうと思います。

f:id:wyumikokh:20171210030142j:plain
カンファレンスブースの様子
カルタの他にFinalFlash2020シェアガチャも展示してわいわいだった

この記事のターゲット

サーバーは全く触ったことないけどWebアプリに挑戦してみたい!という方
Firebaseを手っ取り早く使いはじめてみたい!という方
※てっとりばやく作り始めたい方は「はじめかた」からお読み下さい↓

Firebaseでできること

FirebaseはBaas(Backend as a Service)の1つです。
実装者がバックエンド側の実装をすることなく、決められたAPIを叩くだけでクラウド上に用意された機能群を使うことが出来ます。
Firebaseは多機能すぎるほど多機能なのでここで全て紹介するのは控えますが、
主な機能をサーバーの細かいことはよくわからない人向けにすごく噛み砕いてご紹介します。

  • Realtime Database
    1番の目玉商品!ほぼ※リアルタイムにデータの編集・呼び出しができるデータベースです。
    しかもデータはJSONツリーを介したとってもシンプルなもの(後述)
    設定すればデータのバックアップもちゃんととってくれます。
    クエリが分からなくてもとりあえず大丈夫です。
    ※公式には「数ミリ秒で同期され」とあります

  • Cloud Storage
    画像や音声などのアセットをクラウドに保存できます。(サーバー上で生成したアセットも可)
    他のFirebase機能との親和性も高いです。

  • Firebase Hosting
    コマンド1つで静的サイトを公開できます。無料のSSL証明書つき!

  • Cloud Functions
    バックエンド側で処理してほしい(フロントで見られたらまずい)コードなどはこちらに。

  • Firebase Auth
    SNSログイン機能までつけられちゃいます。

全機能紹介はこちらに 
</> アイコンがついているものがWebで使える機能です。
初心者からベテランまで、ユーザーを厭わないのがFirebaseのすごいところ。

でもお高いんでしょ?

どの機能を使うかにもよりますが、
1番使うであろう Realtime Database だと無料プランで 同時接続100、保存容量1GB、ダウンロードされた容量10GB/月なので
ちょっと触ってみる分には無料プランで十分なようです。
ただ従量制プランもありスケールもしやすいし、なによりバックエンドエンジニアの人件費が削減できるのは大きいですね。

詳しい料金プランはコチラ

フロントエンドあるあるカルタについて

ルールはシンプルなカルタと同じ、読み手が読んだ札をすばやくとって、札がなくなったとき一番多く持ち札を持っていた人が勝ちです。(競技カルタなどでは他にもルールはあると思いますが)

f:id:wyumikokh:20171210023647p:plain

違いは、絵札が表示されるプレイヤーページと、読み札ページがあり、iPadなどのモバイル端末を並べて遊ぶところです。
札はオンラインですが、読み手は真心を込めて肉声で読み上げるため
プレイヤーはその場にいる必要があります。(札を並べるのがらk...

ドタバタで作っていろいろと突っ込みどころは満載だったものの、
当日メンバーが全力でガヤを頑張ってくれたおかげでユーザーの方も楽しんでくれているようで一安心でした。
ガヤの大切さを痛感しましたね・・・(大事)

ちなみにUIのデザインやイラストは弊社のデザイナーオブザイヤー @mazenda_mojya が描いてくれました!
キャラクターモチーフはファイ部(フロントエンドチーム)メンバーですヽ(´エ`)ノ

画像をアップロードしてオリジナル絵札をつくることもできます(ただしConference当日は使う機会がなかった・・)

f:id:wyumikokh:20171210024214p:plain

Firebaseはじめかた

さてここからが本題です。さっそくセットアップしていきましょう。
今回はRealtime Databaseを使えるようになるのがゴールです。
ここからは黒い画面を使います

あると便利なCLIインストール

Node.jsとnpmが必要です。ない方はNode.jsもインストールしておきましょう。

npm install -g firebase-tools

グローバルにCLI(コマンドラインツール)をインストールしました。

firebase --version

を実行してインストールが成功したか確認します。
成功していたら

firebase login

を実行
ブラウザが立ち上がり、googleアカウントの紐付けを行ってくれます。簡単!

プロジェクトの作成

Firebase Consoleでプロジェクトを作成します。
『プロジェクトの追加』から適当な名前を入力してプロジェクトを作るとこんな画面がでてきます

f:id:wyumikokh:20171210023747p:plain

メニューの『DEVELOP』というグループが主にお世話になる機能です。

初期設定

黒い画面にもどって、作業ディレクトリをつくりましょう(今回はpomにします)

mkdir pom
cd pom //作ったディレクトリに移動

さきほどインストールしたFirebase CLIを使ってサイトを初期化します

firebase init

f:id:wyumikokh:20171210023753p:plain

英語で色々きかれてきますね
『RealtimeDatabaseとCloudFunctionsとFirebaseHostingどれを使いたい?(複数選択可)使いたいものをSpaceで選択して、大丈夫だったらEnterキーをおしてね!』と言っています。
次に『プロジェクトを選んでね!』と言ってきます。
先程作ったプロジェクトが表示されていると思うので、選択します。
あとはよしなにfirebaseが設定してくれるので、エンターしておきましょう。

/public以下にhtml、
.firebaserc,database.rules.json,firebase.jsonが生成されたはずです。

Realtime database ルールの設定

先程つくられた database.rules.jsonはデータベースの書き込み権限と読み取り権限の設定を行います。
初期設定は

"rules": {
   ".read": "auth != null",
   ".write": "auth != null"
 }

になっていて、認証されているときしか読み書きができないようになっているので
とりあえず↓のように書き換えましょう。

"rules": {
   ".read": true,
   ".write": true
 }

これで誰でも読み書きができるようになってしまいます。
プロジェクトとして公開するときは厳密に設定する必要があります、が今回は大丈夫です。
https://firebase.google.com/docs/database/security/?hl=ja

書き換えたら、

firebase deploy --only database

でFirerebase consoleにも反映します。
Firebase consoleメニュー>Database>ルール も書き換わっているはずです!

フロントの下準備

フロントのjsでfirebaseを使えるように下準備します。
npmでもfirebaseのモジュールは配布されているのですが、今回は手っ取り早くCDNを使います。
Firebase Consoleで作ったプロジェクト画面の「ここから始めましょう」の右下に『ウェブアプリにFirebaseを追加』というのがあると思うのでクリックします。

f:id:wyumikokh:20171210023639p:plain

ここに出てくるコピーをまるっとコピーして、HTML の一番下、他のスクリプトタグの前に貼り付けましょう。

ようやく下準備が終わりました!

データを追加してみる

const db = firebase.database();
db.ref('/hogehoge').set('pom');

これでfirebase console上でデータが書き換わっているのが確認できました

f:id:wyumikokh:20171210023803p:plain

他にもpushやupdateなどのデータの保存方法があります。
https://firebase.google.com/docs/database/admin/save-data?hl=ja

データを読み取ってみる

下記のように読みとれます。

db.ref('/hogehoge').on('value', function(snapshot) {
    console.log(snapshot.val());
});

valueイベントは、ロード時に1回、その後指定したパス以下のデータが変更される度にJSON形式で呼び出されます。
他の取得イベントはこちらを参照してみて下さい!
https://firebase.google.com/docs/database/admin/retrieve-data?hl=ja

これだけだ!

おわり

いかがでしたか?
私はFirebaseのおかげで自力でできることの可能性が広がりましたヽ(´エ`)ノ

面白法人カヤックでは新しい技術大好き!な人を募集しております!

風邪も流行ってるのでしっかり予防していきましょう・・・!(-_-)

明日は @mamimumemoomoo さんのすごい記事です!

ISUCONで優勝するための筋肉の話

こんにちは!

Tech KAYAC Advent Calendar 2017 8日目を担当する荒賀(@ken39arg)です。

近況報告

お久しぶりです。

昨年のアドベントカレンダーに引き続き今年も筋肉について書けと言われ、すっかり筋肉キャラになってしまいましたがわたしはげんきです。

しかし、業務外の時間は5才と3才のクッソ可愛い息子2人と無限にふざけ続け妻に怒られて凹むか、トレーニングをして筋肉を凸ませるかのどちらかですので間違ってはいないかもしれません。

さてそんな私が今年参戦した主なメジャー大会の結果は下記になります。

30代の目標に掲げているトリプルスリー*3に対しては、1個も達成することができませんでしたが、確かな成長を実感できる1年ではありました。

また、1年を通してずっと Golangでの開発をしていた ためGolang力が付き結果として ISUCONで優勝 することができました。

まえがき

書きたかったこと

Golangを使ってきて良いことはたくさん有るのですが、perlのTMTOWTDIとは真逆で、 goは CodeReviewComments などで良いコードの考え方などが示されているため模範解答のある言語といえます。 このことが、日本的な教育を受けてきた僕にとってはとても心地よくあり楽だと感じている点です。

その中でも、特に素晴らしいと思ったのがTableDrivenTestsで、 なぜ今までこのスタイルでテストを書いてこなかったのだろうかと、後悔するほどわかりやすく書きやすいテスト手法であり、 Goに限らずどの言語でも使える考え方なので、これを今年のアドベントカレンダーのネタにしようと考えていました。

また、ISUCON本戦に際してデータのオンメモリ化がキーだったようですが、自分達の中ではあの状況でオンメモリを選ぶことは自然なことだったので、 オンメモリに対して邪道という考えを持っている方がいることが理解し難いものでした。(ISUCONではという前提があるのかもしれませんが)

そこで、普段自分たちが考えているキャッシュについて、変数レベルから共有ストレージまでを言語化してアドベントカレンダーで書くのも自分にとっての振り返りとしても良いなと考えていました。

実際書くこと

さて、どちらのネタにしようかなあということで、詳細ネタのリストアップとかしていたのですが、マコピーに突然無茶ぶりをされてしまいました。

予定されている内容としては、AWSのアレとアレを組み合わせてみた話や、話題のスマートスピーカーに関する話、カヤックでは硬派なC++の話やISUCONで優勝するための筋肉の話などなど盛り沢山です。

Tech KAYAC Advent Calendar 2017 - KAYAC engineers' blog

ISUCONで優勝したチームメンバーの中に筋肉キャラは他にいないので、「ISUCONで優勝するための筋肉の話」というのは私に書けと言っているのでしょう。

というわけで、前置きが長くなりましたが、私に期待されているのは、技術的なことではなくあくまでも、筋肉とISUCON優勝の関係性についてだと言うことに気づきましたので、 表題の通り自分自身のリフレクションを兼ねて「ISUCONで優勝するための筋肉」について掘り下げて書かせていただきます。

ISUCONで優勝するための筋肉

当記事における筋肉の定義

さて、筋肉といっても様々な筋肉がありますが、今回のテーマとなる筋肉、つまり私が得意としている筋肉について先に明示する必要があると思います。

  • 筋肉≠速筋 ※ 一般的なマッチョ
  • 筋肉=遅筋 ※ マラソンランナーなど
  • 筋肉=脳筋 ※ 脳みそまで筋肉でできている

速筋

私は、非常に不本意ながら小中高と圧倒的に運動神経が悪いクラスタであり、短距離走など瞬発力が重要な速筋については壊滅的です。 また、現在は速筋線維を鍛えようともしていないので、当記事では扱っておりません。

遅筋

逆に、長距離系のスポーツや長時間の練習に耐えることは比較的得意です。 そのため現在長距離系スポーツで成果を上げるために遅筋を鍛えることに関して大変な興味を持っております。 したがって私の言う筋肉とは遅筋のことであります。

(遅筋を鍛えてもゴリッとしたマッチョにはなれませんが、スラッとしているけどそれなりに凹凸のある美しい体型にはなると思うので特に女性は遅筋を中心に鍛えると良いと思います。)

脳筋

脳筋というのはあまりいい表現で使われませんが、私としては考え無しでコードが書ける用になることを表す言葉としてかなりポジティブに考えています。 例として、ISUCONでN+1は何も考えずに直せるとか、深く考えなくてもある程度正しいINDEXを貼れるだとか、 シンプルなCRUD操作程度であれば、考え事をしてても実装できるだとか、そういう無心でやれることの領域を広げたり早くすることを脳筋を鍛えると定義しており、 脳筋を鍛えると重要なことだけに頭を使えるようになると考えております。

  • あたりまえの事を早く省エネでやる能力 = 脳筋
  • 脳筋を鍛える = あたりまえを広げること×スピードを高めること

実際ISUCONで優勝した我々チームMSAは、初出場だったためあたりまえの広さが周りと比べて広いのか狭いのかはわかりませんでしたが、 スピードには自信があったため、「前半のうちに自分たちのあたりまえをすべて終わらせよう」という作戦でした。 結果的に予選も本戦も殆どの時間で脳筋を使っていたのですが、結果的に勝ち切ることができました。

脳筋の鍛え方と遅筋の鍛え方の共通点

実は偉そうに書くほどの正確な知識は無いのですが、遅筋と速筋の鍛え方は真逆で、遅筋は低負荷×長時間の運動速筋は高負荷×短時間の運動で鍛えることができます。

100kgが限界のバーベールを上げ下げするトレーニングを例に挙げると、
「105kgを1回あげるようなトレーニングが速筋に効果的」で
「20kgを100回あげるようなトレーニングが遅筋に効果的」です。

1回もできないことをできるように無理やり頑張るか、できることをより沢山できるように繰り返し頑張るかの違いです。

さて、この出来ることを何度も繰り返すトレーニングというのは脳筋を鍛えるのにも非常に効果的です。 何度もINDEXを張っているとマルチカラムインデックスの順番とか無意識に正解の順番になりますし、N+1クエリを解決するのもどんどん早くなります。

また、このような繰り返しトレーニング(作業)は基本的に苦行なので、少しでも無駄を省いて効率的にやるための努力をするようになります。 その結果、ランニングのフォームを変えたり、コードを生成するツールを作るようなことにも取り組むようになり、結果的に繰り返しの中身が濃くなっていくのです。

ちなみに今私が業務でも使っていてISUCONでも迷わず選択した Golang では考え方の提示だけでなくそれを補助するツールも多数提供されており、無駄なことを考える場面が圧倒的に減ります。(例: gofmt/goimport によってコードフォーマットについて考える必要がなくなる)

退屈な遅筋・脳筋トレーニングのモチベーション管理

遅筋を鍛えるトレーニングと脳筋トレーニングの共通点として退屈ということが挙げられます。 しかし、退屈だからと言ってサボっていると筋力が向上しないどころか低下してしまいます。

そこで退屈を楽しむためのモチベーションの管理が大切になります。

特に下記の2つがモチベーションを維持していくのに重要だと考えています。

  1. 適切な目標設定
  2. 個々のアクションの目的意識

さすがの僕も目標もなく朝4時に起きて20〜30kmを1人で走ったり、100mを100秒のインターバルで20本連続で泳ぎ続けることはできません。 それが可能となるのは、出場する大会と目標タイムを決めそれが現実的になったときです。

現実的になったときというのはポイントな気がして、1年先の大会のためにモチベーションを維持し続けるのは困難ですし、ちょっと不可能な目標を立てても諦めてしまいます。

やはり、現実的にその日が意識できて、なんとか辿り着けそうだとゴールへの道筋が見えてきた時に僕は突然モチベーションが上がって、キツイことが出来るようになります。 (ちなみに今は2ヶ月後のサブスリーという目標が明確なのでとても意識高くトレーニングに取り込めています)

さらに個別のアクションを何のためにやるのか目的意識を持つことは、モチベーション維持することにつながります。

たとえば、このトレーニングではスピードを強化するが、特に太ももの筋肉を強化したいのでトレーニングの目標が達成できなくても太ももがボロボロになればOK。もちろん個別の目標が達成できれば100点。 逆に、目標を達成したとしても目的に対する効果が小さかった時は次回は目標を高くする必要があるかもしれませんし、別の方法を取る必要があるのかもしれません。

こうして目的意識と目標を持つと個々のトレーニング毎にPDCAが自然に出来るようになり、良いサイクルに入ることができます。

これは脳筋でも同じで、単純なことでもそれがどこにつながるためなのかと何のためにやるのかをしっかり意識しつつ、 自分の中で1時間で終わらせようとか目標を決めて取り組んでいくと、単純なことも楽しくなるかと思います。

あらゆる筋肉の強化に回復が大切

さて、遅筋も速筋も脳筋にも共通な超重要事項として、回復することが挙げられます。

単純に疲れていたら、集中力がなくなり、出来ることのレベルも低下してしまうため、結果としてトレーニングの質は下がります。 その為、トレーニングを終えたら次のトレーニングまでにしっかりと回復をする必要があります。

超回復という言葉を聞いたことがある方は多いと思いますが、筋肉はトレーニングで一度壊れ、その回復の過程で少しだけ強化されます。 (ウィルス耐性に似て本能的に壊れたところは次は壊れないように少し強くなると理解しています。)

この壊れた後の少し強化された状態で、次のトレーニングをするとより強化されますが、壊れたままの低下した状態で次のトレーニングをしてしまうとより壊れてしまいます。

したがって、きちんと休息をとり回復し強化された状態で次のトレーニングをするというサイクルをキープすることが重要です。

脳筋を鍛える事も同様で、集中力の無い時にやっても進捗がなくダラダラと長引いてしまい、結果的に更に休息の時間が減っていくという悪循環に陥ります。
逆に、記憶は睡眠中に定着すると言われているように、しっかりと休むことで繰り返したことが定着し次はもっと早く出来るようになり、脳筋のパフォーマンスは向上していきます。

こうして鍛えられた脳筋によって、簡単な事をサクッと終わらせられるようになると、そうではない難しいことにより沢山の時間を割けるようになり、脳筋を使わない分野も成長していくことができます。

とにかく、休息が重要です

皆さんさっさと帰って沢山寝ましょう。

プロテインオブザイヤー2017

さて、ここまで書いたことを改めて読み直すと「何言ってるんだ?すごそうだけど中身空っぽに近い...」というのが私の感想です。 本当にごめんなさい。。。

さて筋肉を早く回復させることで、1週間のうちに効果的に出来るトレーニングの回数を増やすことができるということには、皆さんお気づきかと思います。 そこで回復を早めるのがプロテインです。(プロテインは筋肉でかくするイメージが大きい気がしますが、どちらかというと回復を早めるためのものだと思っています)

また、脳筋も使ったら回復させないといけないのでしっかりとタンパク質を摂ったほうが良いと思います。 そのため僕はプロテインを日々飲んでいます。

実際ISUCON当日の朝もプロテインをのみました

ということで皆さんのお役に立てる、今僕が考えるさいこうのぷろていんを紹介したいと思います。

プロテイン部門

DNSプロテインホエイ100 抹茶

DNSプロテインホエイ100 抹茶 1kg

DNSプロテインホエイ100 抹茶 1kg

圧倒的チャンピオン!!プロテインの革命

プロテインの正解はチョコレートでもイチゴでもバナナでもなく抹茶だったんだと確信させられた極上の逸品。

正直高い!!海外プロテインに比べてお値段はします。 ただ、味は旨すぎて笑えます。少ない水分でも粉溶けは抜群で、そのクリーミーな口当たりは表参道辺りのカフェでインスタに投稿したくなるレベルです。 味は嫌な苦さとか一切なく美味しい抹茶クリームでしかなく、子供に上げたらおかわりを要求されそうなレベルです。 とにかくうまいので金さえあればリピートしたいですが、残念ながら現在はコスパを重視して、海外製プロテインを飲んでいます。

MyProtein

このリンクはアフィリンクなんで私の筋肉となります。(コード: JVDP-R1)

私が現在利用しているプロテインです。

一見安くないように見えますが、何かしらのキャンペーンコードが使えるのでそれを使えば国産プロテインよりは安くなります。 iHerbとかで海外製の3kgとかのデカイのを買うのが一番コスパいいですけど、なかなかなくならないので1kgで1〜2ヶ月くらいでいろんな味を回していくと良いかなと言う感じで使ってます。

(今見たらMyProtein抹茶味が増えていました。今度買ってみよう)

アミノ酸部門

アミノバイタル GOLD

アミノバイタル GOLD 30本入箱

アミノバイタル GOLD 30本入箱

殿堂入り!!!安心安定のアミノバイタルGOLD!!!

持ち運びやすさ、飲みやすさが抜群で、他のBCAAを使っても携行用として常に切らさない用にするべきものです。 普段は海外製のを使いコストを抑え、携行するときはアミノバイタルGOLDで間違いないと思います。

個人的に15年以上前からアミノバイタル飲んでるのでかなり贔屓にしていますが、特に異論は無いのではないのでしょうか?

エクステンド BCAA+シトルリン

私が今週5以上で飲んでいるアミノ酸(BCAA)です。

アミノバイタルは非常に高く定価だと1回200円くらいするので、それこそ1日1回以上飲もうと思うとお財布に優しくないです。 それが海外製だと50円前後で済むものが多いので、持ち運びを意識しない日常使いには海外製がおすすめです。

以前は MRM BCAA+G1000 を飲んでたのですが、効果には不満はありませんが正直マズくて飲む前に気合が必要なときもあったので、味の評判が良さそうなこちらに変更しました。

かなり甘いので最初はウッとなりましたが、なれるとその甘さが美味しいと感じるから不思議です。 ただし、甘い匂いを撒き散らすので注意が必要です。

まとめ

長々と書きましたが、脳筋を鍛えたらISUCONで優勝出来るし、脳筋の鍛え方は遅筋鍛えればわかるし、退屈を乗り切るには楽しむ工夫をしたら良いし、まとめると残業しないで早く寝ろ!ということを言いたかったのでした。

カヤックでは脳筋を鍛えてISUCONで優勝したいサーバーサイドエンジニアを募集しています。 また、僕と一緒にサブスリーを目指して一緒にトレーニングをしている仲間も募集しております。

明日は@yumikokhによるなんかすごそうなやつです。 2日続けてテック感なかったので明日は期待!!!

*1:逗子から江ノ島まで10kmを泳ぐ大会で、10kmを泳ぐOWSはオリンピック種目でもあります

*2:お題となるWebサービスを決められたレギュレーションの中で限界まで高速化を図るチューニングバトル、それがISUCONです。

*3:フルマラソンオープンウォータースイミング10kmトライアスロンのオリンピック長距離種目3種でサブスリー(3時間切り)を達成することを私が勝手にトリプルスリーと言っています。