福岡から世界中の"むずかしい"を簡単にする株式会社diffeasyCTOの西@_takeshi_24です。
この記事はアドベントカレンダー「diffeasyCTO西の24(にし)日連続投稿チャレンジ Advent Calendar 2019」の5日目の記事です。
この記事は「Nuxt.jsとFirebaseとCloudFunctionsでWebアプリ開発」シリーズとして、連載していきます。
Nuxt.jsとFirebaseなどを使ってWebアプリケーション開発にチャレンジしたい方、是非Qiitaアカウントかtwitterをフォローしていただき、ツッコミやいいね!お願いします!
はじめに
こちらの記事は、「Nuxt.jsとFirebaseとCloudFunctionsでWebアプリ開発」シリーズとして連載していますので、過去の記事もご覧ください。
##RealtimeDatabaseとCloudFirestore
FirebaseのデータベースにはRealtimeDatabaseとCloudFirestoreの2種類があります。
データベースを選択: Cloud Firestore または Realtime Databaseにも解説がありますが、それぞれ特徴を簡単に説明すると、
- RealtimeDatabase:レイテンシが低く、シンプルなリアルタイム処理に向いている。
- CloudFirestore:RealtimeDatabaseよりもクエリが柔軟で高速。
といった感じです。
##Nuxt.jsでRealtimeDatabase
以前の記事ではvuexfireというパッケージを使っていましたが、最近はあまりメンテナンスされていないようです。
vuexfireを使わなくても、簡単にNuxt.jsからFirebaseのRealtimeDatabase、Firestoreを扱えますので、今回はその方法を説明します。
まずはFirebaseのRealtimeDatabaseにデータを書き込み、リアルタイムで表示します。
messagesというコレクションにmessageTextという値を追加します。
1./pages/messages/index.vueを以下の内容で作成します。
<template>
<section class="container">
<v-row>
<v-col>
<v-text-field v-model="messageText"></v-text-field>
</v-col>
<v-col>
<v-btn @click="addMessage">投稿</v-btn>
</v-col>
</v-row>
<v-row v-for="(message, key, index) in messages" :key="index">
<v-col>
<p>
{{ message.messageText }}
</p>
</v-col>
</v-row>
</section>
</template>
<script>
import firebase from "firebase";
export default {
data() {
return {
messages: [],
messageText: ""
};
},
mounted() {
this.initMessages();
},
methods: {
initMessages() {
firebase
.database()
.ref("messages")
.on("child_added", snapshot => {
this.messages.unshift(snapshot.val());
});
},
addMessage() {
firebase
.database()
.ref("messages")
.push({ messageText: this.messageText });
this.messageText = "";
}
}
};
</script>
2.yarn run dev
で起動して、テキストにメッセージを入力し、「投稿」ボタンをクリックします。
3.Permission denied
のエラーが返ってきます。RealtimeDatabaseに対する書き込み権限がないためです。ログインユーザーのみ、RealtimeDatabaseの読み込み書き込みができるように、firebase.json
と同じ場所にあるdatabase.rules.json
ファイルを修正します。
{
"rules": {
"messages": {
".read": "auth != null",
".write": "auth != null"
}
}
}
4.DBルールをデプロイします。
$ firebase deploy --only database
5.もう一度テキストにメッセージを入力し、「投稿」ボタンをクリックします。今度は投稿できて、投稿した内容がリアルタイムで表示されました。
##Nuxt.jsでCloudFirestore
次に、Firestoreのusersコレクションにログイン中のユーザー情報を登録処理を作ります。
1./pages/current_user/index.vueを以下の内容で作成する。
<template>
<section class="container">
<v-row>
<v-col>
<v-text-field v-model="familyName" placeholder="姓"></v-text-field>
</v-col>
<v-col>
<v-text-field v-model="firstName" placeholder="名"></v-text-field>
</v-col>
<v-col>
<v-btn @click="updateUser">更新</v-btn>
</v-col>
</v-row>
</section>
</template>
<script>
import firebase from "firebase";
const db = firebase.firestore();
export default {
data() {
return {
uid: "",
firstName: "",
familyName: ""
};
},
created() {
firebase.auth().onAuthStateChanged(user => {
this.uid = user.uid;
this.getUser();
});
},
methods: {
async getUser() {
const userRef = db.collection("users").doc(this.uid);
const userDoc = await userRef.get();
if (userDoc.exists) {
this.firstName = userDoc.data().firstName;
this.familyName = userDoc.data().familyName;
}
},
updateUser() {
db.collection("users")
.doc(this.uid)
.set({
firstName: this.firstName,
familyName: this.familyName
});
}
}
};
</script>
firebaseの認証情報が非同期で取得されますので、firebase.auth().onAuthStateChangedでログインユーザーのuidを取得します。
getUser()でログインユーザーの情報を取得して、updateUser()でログインユーザーの情報を更新しています。
通常のサービスであれば、セッション情報などを使って、サーバーサイドでUIDを取得すれば安全ですが、BaaSのFirebaseをNuxt.jsから呼ぶ場合、クライアントからUIDをサーバーに渡す必要があります。
クライアント側でUIDを渡しているので、当然改竄しようと思えば、改竄可能です。
他人のUIDのデータを改竄されたら問題なので、Firestore側でデータ更新ルールを使ってデータを保護する必要があります。
2.firebase.json
と同じ場所にあるfirestore.rules
ファイルを修正します。
service cloud.firestore {
match /databases/{database}/documents {
match /users/{userId} {
allow read, update, delete: if request.auth.uid == userId;
allow create: if request.auth.uid != null;
}
}
}
usersコレクションのuserIdとログインユーザーのUIDが一致していれば、読み込み、更新、削除可能で、ログイン中であれば登録できるルールに設定します。
なお、今回getUser()でcreated時にusersコレクションのデータを取得していますが、リアルタイムで取得するには、onSnapshotを利用すると、リアルタイムで取得できます。
データの更新処理には、データ一貫性を保持する必要があり、トランザクションは必須です。
Firebaseのトランザクションについてはまた今後の記事で紹介します。
##最後に
この記事は「Nuxt.jsとFirebaseとCloudFunctionsでWebアプリ開発」シリーズとして、連載していきます。
続きはアドベントカレンダー「diffeasyCTO西の24(にし)日連続投稿チャレンジ Advent Calendar 2019」に掲載していきます。
Nuxt.jsとFirebaseなどを使ってWebアプリケーション開発にチャレンジしたい方、是非Qiitaアカウントかtwitterをフォローしていただき、ツッコミやいいね!お願いします!
#advent_24のハッシュタグでフィードバックいただけると嬉しいです!