Vue3を使ってRealtime Databaseをマスターしよう
こんにちはあっくんです。最近、急に涼しくなってきましたね。ほんと寒いくらいですね。みなさん、体調はいかがでしょうか?僕は、季節の変わり目に対応できず、肌が乾燥していて結構つらいです。どうかみなさん体調には気をつけてくださいね。僕は現在、就職活動がなかなかうまくいかず、体調とメンタルも沈んでいましたが、ここからあきらめず取り組んでみます。今回はFirebaseのRealtime Databaseを使って、データの保存、削除をやっていきましょう。
インデックスを追記する
Firebaseのデータをさまざまな検索をするために「インデックス」の設定が必要です。FirebaseはNoSQLで複雑なアクセスは行なえません。なので、「インデックス」と呼ばれるものを設定し、データの取り出しを知らせる必要があります。
ルールを修正する
Firebaseコンソールにアクセスし、Realtime Databaseをクリックしましょう。
↑作成したプロジェクトのデータベースを開いたところ。
データベースの内容が表示されているエリアの上部にある「ルール」というリンクをクリックしましょう。これで、データベースアクセスの設定が表示されます。
↑「ルール」をクリックすると設定が表示されます。
JSONデータとして設定が用意されています。これに、項目のインデックスに関する設定情報を追加します。
"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
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)
↑キーとなるメールアドレスを記入しボタンを押すと、そのデータを表示します。
検索のための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)
↑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)
↑フォームに入力ボタンを押すと、その内容が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)
↑キーとなるメールアドレスを入力し、ボタンを押すと、そのキーのデータが削除されます。
削除処理チェック
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超入門で勉強をしています。語りかけるような文章ですごいわかりやすいです。本当におすすめです。