目次

10.Vue.jsとFirebaseでランキングつき連打ゲーム

以前、Nifty Cloud Mobile Backendのサイトのサンプルコードを参考に、Ionic3とFirebaseによるオンラインランキングつきタップゲームを作ったことがありました。ソースコードはこちらです。

https://github.com/adash333/ionic3_firebase_renda

今回は、同じことをCodesandboxのVue.js上でやってみたいと思います。

方針をたてる

今回作成するタップゲームは、

  1. 10秒間で何回マトをタップできるか競うゲーム(爆)
  2. Firebaseを利用するために、トップページHome.vueに、「匿名ログイン」ボタンを表示
  3. ログインしなくても遊べる
  4. ログインすれば、firebaseにスコアと名前を登録(write)したり、ランキングを見る(read)ことができる

となります。

今回は、https://github.com/adash333/ionic3_firebase_rendaを参考にしたいと思います。

ソースコード 作成中
https://codesandbox.io/s/zz97y131m4

作ったもの 作成中

0.用意するもの(開発環境)

パソコン
Chrome(くろーむ、WEBブラウザの一つ)
GitHubアカウント作成済み(無料)
Googleアカウント作成済み(無料)

パソコンは、Windowsパソコンでも、Macでも、かまいませんが、私の場合はWindows 10 Proとなります。

今回利用するもの

CodeSandbox
Firebase (real time databse)
Vue 2.5.2
Vuetify
firebase

新規Firebaseアプリの作成

09.emailとpasswordでパスワード制限と同様に、Firebaseアプリを作成し、apiキーなどをメモ帳などに保存しておきます。

なお、Realtime Databaseを作成し、ルールは以下のようにしておきます。

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

Codesandboxで新規Vue.jsアプリの作成

App.vueの編集

<template>
  <div id="app">
    <v-toolbar color="indigo" dark fixed app>
      <v-toolbar-title>Vue Vuetify Firebase 連打ゲーム</v-toolbar-title>
    </v-toolbar>
    <v-app id="inspire">
      <v-content>
        <v-container fluid fill-height>
          <v-layout align-center justify-center>
            <v-flex xs12 sm8 md4>
              <v-card class="elevation-12">
                <v-toolbar dark color="primary">
                  <v-toolbar-title>Login form</v-toolbar-title>
                  <v-spacer></v-spacer>
                </v-toolbar>

                <v-card-text> 匿名ユーザーでログイン </v-card-text>

                <v-card-actions>
                  <v-spacer></v-spacer>
                  <v-btn color="primary" @click="login">Login</v-btn>
                </v-card-actions>
              </v-card>
            </v-flex>
          </v-layout>
        </v-container>
      </v-content>
    </v-app>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {};
  },
  components: {},
  created() {
    firebase.auth().onAuthStateChanged(user => {
      if (user) {
        // User is signed in.
        console.log("is login.");
      } else {
        // No user is signed in.
        console.log("No user is signed in.");
      }
    });
  },
  methods: {
    login() {
      firebase
        .auth()
        .signInAnonymously()
        .then(e => {
          // ログイン成功
          console.log(e);
        })
        .catch(error => {
          // エラーメッセージ
          var errorCode = error.code;
          var errorMessage = error.message;
          console.log("エラーメッセージ", errorCode, errorMessage);
        });
    }
  }
};
</script>

<style></style>

作成中

Vue.jsとFirebaseのリンク

https://qiita.com/renowan/items/bf1747aabc874bfd85ab
@renowan
2017年10月31日に更新
Vue.jsでFirebaseを始めよう 3.ユーザーログイン編

https://liginc.co.jp/382652
2018.03.07
Vue.js + Firebaseでチャットアプリを脳死しながら作ってみよう!〜完成編〜
はっちゃん

https://qiita.com/you8/items/b0025651988f59da1a08
@you8
2018年01月09日に投稿
vue.js+firebase+vuefireで作るチャット

https://qiita.com/unotovive/items/91e1b232c44211d4ed2f
@unotovive
2018年06月16日に更新
Vue.js2+Vuefire+firebaseその他もろもろで欲しいもの管理アプリ

https://qiita.com/magaya0403/items/e292cd250184ea3fe7b0
@magaya0403
2018年06月08日に投稿
Vue.js + FirebaseでTodoアプリを作る

https://ueqareer.net/2770
2018.10.07 webデザイン
Vue.js + FirebaseでToDoアプリを構築

FirebaseのRealtime Databaseのセキュリティルール

https://qiita.com/mironal/items/b93742e8ef72b3268beb
@renowan
2017年10月31日に更新
Vue.jsでFirebaseを始めよう 4.送信してみる編

Vuetifyのv-imgの相対パスでの画像がうまく表示されない

https://vuetifyjs.com/ja/getting-started/frequently-asked-questions
の一番下のFAQ

Relative images are not working in v-card , v-img and other custom vuetify components

Vue loader converts relative paths into require functions automatically for you. Unfortunately, this is not the case when it comes to custom components. You can circumvent this issue by using require.

例えば、src/components/Hello.vueにおいて、src/assets/target.jpgを表示するためには、以下のような記載方法となる。
(Vuetify使用するために、かなり面倒なことになっている。これは、Vuetifyの最大の欠点かもしれない。。。どうりで、Vuetifyの公式サイトでは、いつも、v-img のsrcがhttps:から始まっているわけだ。。。)

<template>
<v-img :src="image_src" max-width="250px"></v-img>
</template>

<script>
data() {
  return {
    image_src: require("../assets/target.jpg"),
  }
}    
</script>

画像を水平真ん中にするためには、<v-layout justify-center></v-layout>で囲む。
https://codepen.io/CasperLai/pen/pwMrMg

Vuetifyのボタン

https://vuetifyjs.com/ja/components/buttons

(参考)Ionic3とfirebaseでランキングつきタップゲーム

<Ionic3+Firebaseでタップゲーム 目次>
(1)ビュー(html)の作成とAngularfire2の準備
(2)タップゲームをHomePageに実装(Ionic3でjQueryを利用)
(3)rankingの作成

http://twosquirrel.mints.ne.jp/?p=24596

http://twosquirrel.mints.ne.jp/?p=24690

http://twosquirrel.mints.ne.jp/?p=24741

ソースコード:https://github.com/adash333/ionic3_firebase_renda

(開発環境)

Windows 8.1 Pro
VisualStudioCode
git version 2.16.1.windows.4
Sourcetree Version 2.4.8.0
Android Studio 3.0.1

Node v8.11.2
npm 6.1.0
@ionic/cli-utils 1.19.2
Ionic (Ionic CLI) 3.20.0

firebase@4.8.0
angularfire2@5.0.0-rc.4
promise-polyfill@8.0.0

https://qiita.com/okame_qiita/items/d8d85906b88e33ba0eff
@okame_qiita
2017年11月09日に更新
jQuery→JavaScript書き換え一覧表

Vue.jsではgetElemetByIdの代わりにデータバインディング{{msg}}を用いる

たとえば、Htmlファイルで、

<p id="first">テキスト</p>

の“テキスト”の部分を“変更後”に変更したい場合、
jQueryでは

$('p#first').text('変更後');

とします。Javacriptでは、

document.getElementById('first').textContent = '変更後'

とします。その代わりとして、Vue.jsでは、データバインディングを用います。
Vue.js

<template>
<p>{{ msg }}</p>
</template>

<script>
data() {
  return {
    msg: "テキスト"
  }
},
methods: {
  changeMsg() {
    this.msg = "変更後"
  }
}
</script>

これに気付くのに、Ionic3の時代からあわせて1年くらいかかりました。。。

Vuetifyでテーブル

最初は、かなりややこしい感じがしますが、慣れれば割と簡単に降順に記載したりできるようです。

https://commis.hatenablog.com/entry/2018/05/29/102606
20180529
VuetifyのData tableを指定列の降順で初期表示する

https://jsbin.com/gedaqud/edit?html

公式ドキュメント
https://vuetifyjs.com/ja/components/data-tables

javascriptの配列とオブジェクト

配列について

http://proengineer.internous.co.jp/content/columnfeature/8632
JavaScriptの配列オブジェクトの使い方
20180730

http://proengineer.internous.co.jp/content/columnfeature/8841
JavaScriptの配列要素の値を追加/削除する方法
20180817

連想配列(オブジェクト)について

http://proengineer.internous.co.jp/content/columnfeature/8887
JavaScriptの連想配列を使ってみよう!
20180820

今回のコードで、一番難しいところ。
ここは、https://qiita.com/renowan/items/b8222f2b873cc29a462d のコードをコピペしたのですが、詳しいところはさっぱりわかりません。

   listen: function() {
      firebase
        .database()
        .ref("gameScores/")
        .on("value", snapshot => {
          // eslint-disable-line
          if (snapshot) {
            const rootList = snapshot.val();
            let list = [];
            Object.keys(rootList).forEach((val, key) => {
              rootList[val].id = val;
              list.push(rootList[val]);
            });
            this.list = list;
            //スコア順に並び替え
            this.list.sort(function(a, b) {
              return a.score > b.score ? -1 : 1;
            });
          }
        });
    },

以下のコードでもよい?
https://ueqareer.net/2770/3

   <!-- todoの一覧表示 -->
    <ul v-for="(todo, key) in filteredTodos" :key="todo.id">
      <li><input class="toggle" type="checkbox" v-model="todo.isComplete" v-on:click="updateIsCompleteTodo(todo, key)">{{ todo.name }}</li>
      <button type="submit" v-on:click="deleteTodo(key)">削除</button>
    </ul>
  created: function() {
    this.database = firebase.database();
    this.uid = firebase.auth().currentUser.uid;
    this.todosRef = this.database.ref("todos/" + this.uid);
 
    var _this = this;
    // データに変更があると実行されるfunction
    this.todosRef.on("value", (snapshot) => {
      this.todos = snapshot.val(); // 再取得してtodosに格納する
    });
  },
  

FirebaseのRTDBのobjectをarrayに変換する

Firebaseドキュメント
https://firebase.google.com/docs/database/admin/retrieve-data

// Import Admin SDK
var admin = require("firebase-admin");

// Get a database reference to our posts
var db = admin.database();
var ref = db.ref("server/saving-data/fireblog/posts");

// Attach an asynchronous callback to read the data at our posts reference
ref.on("value", function(snapshot) {
  console.log(snapshot.val());
}, function (errorObject) {
  console.log("The read failed: " + errorObject.code);
});

スナップショットの val() / getValue() を呼び出すと、データの言語固有のオブジェクト表現が返されます。

とのことです、、、console.log(snapshot.val())の中身をコンソール画面で確認するしかなさそうです。

        const rootList = snapshot.val();
            let list = [];
            Object.keys(rootList).forEach((val, key) => {
              rootList[val].id = val;
              list.push(rootList[val]);
            });

rootListが、firebaseから受け取ったobject

これを、listという配列arrayに変換する。

結局、object{ }の中身のvalueを並べて、[ ]でくくった配列arrayにしているのだと解釈しました。
(間違っていたらすみません、、、)

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
Object.keys()メソッドについて

Object.keys(object1)で、連想配列object1のキーkeyの配列arrayを得ます。

const object1 = {
  a: 'somestring',
  b: 42,
  c: false
};

console.log(Object.keys(object1));
// expected output: Array ["a", "b", "c"]

forEach文

https://www.sejuku.net/blog/20257
【JavaScript入門】forEach文の使い方と配列の繰り返し処理まとめ!
2016年 by マサト

forEach文のコールバック関数

array.forEach( function( value, index, array ) {
 
  // 繰り返し処理を書く
 
});

value:配列データの値
index:配列のインデックス番号
array:現在処理している配列

https://qiita.com/nantekkotai/items/6c603b40ac2264e9f6f6
@nantekkotai
2014年02月21日に更新
JSのObjectをforEachで処理する方法

https://chaika.hatenablog.com/entry/2016/06/21/085000
2016-06-21
Javascript 連想配列(オブジェクト)をforEachでループさせたい。

https://ilikekillnerds.com/2017/05/convert-firebase-database-snapshotcollection-array-javascript/
Convert A Firebase Database Snapshot/Collection To An Array In Javascript
Last updated: March 8, 2018

リンク