あっくんブログ Written by Akihiro Tsuji

Vue3を使ってRealtime Databaseをマスターしよう

Vue.js プログラミング

こんにちはあっくんです。最近、急に涼しくなってきましたね。ほんと寒いくらいですね。みなさん、体調はいかがでしょうか?僕は、季節の変わり目に対応できず、肌が乾燥していて結構つらいです。どうかみなさん体調には気をつけてくださいね。僕は現在、就職活動がなかなかうまくいかず、体調とメンタルも沈んでいましたが、ここからあきらめず取り組んでみます。今回はFirebaseのRealtime Databaseを使って、データの保存、削除をやっていきましょう。

インデックスを追記する

Firebaseのデータをさまざまな検索をするために「インデックス」の設定が必要です。FirebaseはNoSQLで複雑なアクセスは行なえません。なので、「インデックス」と呼ばれるものを設定し、データの取り出しを知らせる必要があります。

ルールを修正する

Firebaseコンソールにアクセスし、Realtime Databaseをクリックしましょう。

Image from Gyazo

↑作成したプロジェクトのデータベースを開いたところ。

データベースの内容が表示されているエリアの上部にある「ルール」というリンクをクリックしましょう。これで、データベースアクセスの設定が表示されます。

Image from Gyazo

↑「ルール」をクリックすると設定が表示されます。

JSONデータとして設定が用意されています。これに、項目のインデックスに関する設定情報を追加します。

Image from Gyazo

"person": {
".indexOn":["name", "tel", "age"]
},

これは「person」データに「indexOn」という設定を追加するものです。これにより、name,tel,ageの項目にインデックスが追加され、それらで値の並べかえとフィルター処理ができるようになります。

キーによる検索を書き直す

それでは、インデックスを利用した検索を行っていきましょう。axiosをインストールしていきましょう。realtime_database_appプロジェクトをViteで作ってやっていきましょう。

開発するディレクトリでターミナルに↓のように記述してrealtime_database_appを作って、npmをインストールします。

npm init vite-app realtime_database_app

cd realtime_databgase_app
npm install

npm install axios

Realtime Databaseをマスターしよう

index.htmlとApp.vueとHelloWorld.vueを修正して確認していきましょう。

index.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="icon" href="/favicon.ico" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>realtime_database</title> <!-- CSS only --> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous" /> <!-- JavaScript Bundle with Popper --> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous" ></script> </head> <body> <h1 class="bg-secondary text-white h4 p-3">Vue3 Realtime_database</h1> <div class="container"> <div id="app"></div> </div> <script type="module" src="/src/main.js"></script> </body> </html>
Code language: HTML, XML (xml)

App.vue

<template> <div id="app"> <HelloWorld /> </div> </template> <script> import HelloWorld from "./components/HelloWorld.vue"; export default { name: "App", components: { HelloWorld, }, }; </script>
Code language: HTML, XML (xml)

HelloWorld.vue

<template> <section class="alert alert-primary"> <h1>{{ data.title }}</h1> <p>{{ data.message }}</p> <div class="row my-2"> <div class="col-sm-auto"> <input type="text" v-model="data.find" class="form-control" /> </div> <button class="col-sm-auto btn btn-primary" @click="getData"> Click </button> </div> <div class="alert alert-light">{{ data.fire_data }}</div> </section> </template> <script> import axios from "axios"; import { onMounted, reactive } from "vue"; let url = "https://akkun-vue3-50410-default-rtdb.firebaseio.com/person.json?orderBy=%22$key%22&equalTo=%22"; export default { setup(props) { const data = reactive({ title: "Firebase", message: "This is Firebase sample.", find: "", fire_data: {}, }); const getData = () => { let id_url = url + data.find + "%22"; axios .get(id_url) .then((result) => { data.message = "get ID" + data.find; if (result.data != null) { data.fire_data = result.data; } else { data.fire_data = "no data found..."; } }) .catch((error) => { data.message = "ERROR!"; data.fire_data = {}; }); }; onMounted(() => { getData(); }); return { data, getData }; }, }; </script>
Code language: HTML, XML (xml)
Image from Gyazo

↑キーとなるメールアドレスを記入しボタンを押すと、そのデータを表示します。

検索のためのURLをチェック

let url ="https://akkun-vue3-50410-default-rtdb.firebaseio.com/person.json?orderBy=%22$key%22&equalTo=%22";

let id_url = url + find + '%22'

これでキーによる検索を行うアドレスができました。

~person.json?orderBy="$key"&equalTo="検索テキスト"

ここでperson.jsonの後に、?と&記号を付けています。これは、「クエリーテキスト」と呼ばれるもので、アドレスを使って必要な情報をサーバーに送るのに用いられます。

orderBy="$key"

検索の際には、まずこれを用意する必要があります。このorderByはどの項目でデータを並べ返るかを指定するものです。キーから検索するので、”$key”としています。

equalTo="検索テキスト"

このequalToは指定した値とデータを取り出すためのものです。例えば、equalTo=”a”とすれば、orderByで指定した項目の値が”a”のものだけを取り出します。

%22って?

orderBy =”$key” → orderBy=%22$key%22

↑の2つは同じものです。Webのアドレスは、”などの記号類は直接記入することはできません。このため、特殊なコードに変換して記述します。”記号は、%22と記述します。

年齢の範囲を指定して検索

ageを使って、「○○歳以上○○歳以下」というデータを検索してみます。HelloWorld.vueを修正します。

HelloWorld.vue

<template> <section class="alert alert-primary"> <h1>{{ data.title }}</h1> <p>{{ data.message }}</p> <div class="row my-2"> <div class="col-sm-auto"> <input type="text" v-model="data.find" class="form-control" /> </div> <button @click="getData" class="col-sm-auto btn btn-primary"> Click </button> </div> <ul v-for="(item, key) in data.fire_data" class="list-group"> <li class="list-group-item text-start"> <strong>{{ key }}</strong ><br />{{ item }} </li> </ul> </section> </template> <script> import axios from "axios"; import { reactive } from "vue"; let url = "https://akkun-vue3-50410-default-rtdb.firebaseio.com/person.json?orderBy=%22age%22"; export default { setup(props) { const data = reactive({ title: "Firebase", message: "This is Firebase sample.", find: "", fire_data: {}, }); const getData = () => { let range = data.find.split(","); let age_url = url + "&startAt=" + range[0] + "&endAt=" + range[1]; axios .get(age_url) .then((result) => { data.message = "get ID=" + data.find; if (result.data != null) { data.fire_data = result.data; } else { data.fire_data = "no data found..."; } }) .catch((error) => { data.message = "ERROR!"; data.fire_data = {}; }); }; return { data, getData }; }, }; </script>
Code language: HTML, XML (xml)
Image from Gyazo

↑30,50と打ち込むと、最小と最大の年齢をカンマで区切って記述してボタンを押すと、その範囲のデータを検索し表示します。

startATとendAt

~person.json?orderBy="age"&startAt=開始&endAt=終了

ここではクエリーテキストの部分に3つの項目を用意しています。

orderBy="age"

ageを指定しています。

startAt=開始

データの開始の値を指定するものです。指定した値以降のものを取り出します。

endAt

これはデータの終了の値を指定するものです。

データを追加する

データの追加は↓のようにアクセスします。

https://プロジェクト.firebaseio.com/person/キー.json

データを保存するキーをアドレスの最後に「キー.json」という形で指定します。axiosの「put」というメソッドでアクセスを行います。

axios.put(アドレス, オブジェクト)

第1引数にデータを追加するキーを指定したアドレスを用意し、第2引数に保管するオブジェクトを用意して呼び出します。これで指定のキーにオブジェクトが値として追加されます。すでに使われているキーは上書きされます。

personにデータを追加する

それでは、Firebaseのpersonに新たにデータを追加するサンプルを作っていきましょう。HelloWorld.vueを修正します。

HelloWorld.vue

<template> <section class="alert alert-primary"> <h1>{{ data.title }}</h1> <p>{{ data.message }}</p> <div class="text-start"> <div class="form-group"> <label for="">Email</label ><input type="text" v-model="data.email" class="form-control" /> </div> <div class="form-group"> <label for="">Name</label ><input type="text" v-model="data.username" class="form-control" /> </div> <div class="form-group"> <labal>Age</labal> <input type="text" v-model="data.age" class="form-control" /> </div> <div class="form-group"> <label for="">Tel</label ><input type="text" v-model="data.tel" class="form-control" /> </div> <button @click="addData" class="btn btn-primary my-3">Click</button> <ul v-for="(item, key) in data.fire_data" class="list-group"> <li class="list-group-item text-start"> <strong>{{ key }}</strong ><br /> {{ item }} </li> </ul> </div> </section> </template> <script> import axios from "axios"; import { onMounted, reactive } from "vue"; let url = "https://akkun-vue3-50410-default-rtdb.firebaseio.com/person"; export default { setup(props) { const data = reactive({ title: "Firebase", message: "This is Firebase sample.", email: "", username: "", tel: "", age: 0, fire_data: {}, }); const addData = () => { if (data.username == "") { console.log("no-username!"); return; } let add_url = url + "/" + data.email + ".json"; let item = { name: data.username, age: data.age, tel: data.tel, }; axios.put(add_url, item).then((re) => { data.email = ""; data.username = ""; data.age = 0; data.tel = ""; getData(); }); }; const getData = () => { let all_url = url + ".json"; axios .get(all_url) .then((result) => { data.message = "get all data."; data.fire_data = result.data; }) .catch((error) => { data.message = "ERROR!"; data.fire_data = {}; }); }; onMounted(() => { getData(); }); return { data, addData, getData }; }, }; </script>
Code language: HTML, XML (xml)
Image from Gyazo

↑フォームに入力ボタンを押すと、その内容がFirebaseに追加されます。

スクリプトをチェック

4つのフィールドを用意しています。それぞれ、V-modelを使いemail,username,tel,ageといった値をバインドしています。今回は、アクセス先のアドレスのベースとして以下のような値を用意しています。

let url = "https://プロジェクト.firebase.com/person"

新たにデータを追加するときは、この後に”/キー.json”というようにしてアクセスすれば、指定のキーにデータを追加できます。全データがほしければ、この後に、”.json”とつけてアクセスできます。データの追加はaddData関数で行っています。emailをキーにしています。

let add_url = url + '/' + data.email + '.json'

username,age,telを1つのオブジェクトにまとめます。

let item = { 'name': data.username, 'age': data.age, 'tel': data.tel }
Code language: JavaScript (javascript)

アドレスと値のオブジェクトが用意できたらaxios.putを使ってアクセスします。そして作業終了後は、各フィールドを初期状態にもどし、全データの表示を行うgetDataを呼び出しておきます。

<meta charset="utf-8">axios.put(add_url, item).then((re) => { data.email = ""; data.username = ""; data.age = 0; data.tel = ""; getData(); });
Code language: JavaScript (javascript)

後は、全データを取得して表示するgetData関数です。これは、urlに’.json’をつけたアドレスにaxios.getでアクセスし、取り出したデータをfire_dataに設定します。

const getData = () => { let all_url = url + ".json" axios .get(all_url) .then((result) => { data.message = "get all data." data.fire_data = result.data }) .catch((error) => { data.message = "ERROR!" data.fire_data = {} }) }
Code language: JavaScript (javascript)

データの削除

データの削除のときのfirebaseのアドレスは

https://プロジェクト.firebaseio.com/person/キー.json

削除のときはaxiosで呼び出すメソッドは 「delete」というメソッドを使います。

axios.delete(アドレス)


これで、アクセスしたアドレスのキーをデータベースから削除します。

Firebaseからデータを削除する

HelloWorld.vue

<template> <section class="alert alert-primary"> <h1>{{ data.title }}</h1> <p>{{ data.message }}</p> <div class="text-start"> <div class="form-gruop"> <label for="">Email</label ><input type="text" v-model="data.email" class="form-control" /> </div> <button @click="delData" class="btn btn-primary my-3">Click</button> </div> <ul v-for="(item, key) in data.fire_data" class="list-group"> <li class="list-group-item text-start"> <strong>{{ key }}</strong >{{ item }} </li> </ul> </section> </template> <script> import axios from "axios"; import { onMounted, reactive } from "vue"; let url = "https://akkun-vue3-50410-default-rtdb.firebaseio.com/person"; export default { setup(props) { const data = reactive({ title: "Firebase", message: "This is Firebase sample.", email: "", fire_data: {}, }); const delData = () => { if (data.email == "") { console.log("no-username!"); return; } let del_url = url + "/" + data.email + ".json"; axios.delete(del_url).then((re) => { data.message = data.email + "を削除しました。"; data.email = ""; getData(); }); }; const getData = () => { let all_url = url + ".json"; axios .get(all_url) .then((result) => { data.fire_data = result.data; }) .catch((error) => { data.message = "ERROR!"; data.fire_data = {}; }); }; onMounted(() => { data.message = "get all data."; getData(); }); return { data, delData, getData }; }, }; </script>
Code language: HTML, XML (xml)
Image from Gyazo

↑キーとなるメールアドレスを入力し、ボタンを押すと、そのキーのデータが削除されます。

削除処理チェック

let url = "https://プロジェクト.firebaseio.com/person"

これに削除するキーを追加してアクセス先のアドレスを完成させます。

let del_url = url + '/' + data.email + '.json'

これで「~/person/メールアドレス.json」といったアドレスができました。これをdelData関数で削除処理します。

axios.delete(del_url).then((re)=> { data.message = data.email + 'を削除しました。' data.email = '' getData() })
Code language: JavaScript (javascript)

axios.deleteで削除を実行。実行後に呼び出されるthenの関数でmessageとemailの値を変更し、getDataを呼び出して表示データを更新します。

Realtime Databaseのポイントは、アドレス

Realtime Databaseを使いこなすポイントはアドレスです。Realtime DatabaseはJSON形式のデータを管理します。JSONデータというのは{}の中にキーと値が組み込まれている形です。この「キーと値」が重要です。Firebaseではデータにアクセスする際は最後に「.json」をつけてアクセスします。
 アクセスするときのaxiosの操作で使うメソッドは以下の様になります。

get
データを取り出します

put
データを保存します

delete
データを削除します

ここまで読んでいただいてありがとうございます。VueとFirebaseを使って簡単なアプリケーションを作って見ようと思います。
掌田津耶乃さんのVue.js3超入門で勉強をしています。語りかけるような文章ですごいわかりやすいです。本当におすすめです。