この記事はただの集団 Advent Calendar 2019の5日目の記事です。
( 内容が薄くて大変申し訳ありません )
ざっくりFirestore + Vue.jsの使い方
フロントエンドでも簡単にサーバーサイド込みで実装できると噂のFirebase
を
いじってみたので簡単にですがFirebase
のサービスの一つFirestore
についてまとめてみました。
● Firestoreについて
Firestore
は Realtime Database
の進化版のようなものです。
ドキュメント指向のいわゆる NoSQL
と言われるタイプのDBで、
MongoDBとかDynamoDBと同じカテゴリに入るやつです。
● 開発環境
- Mac : Mojave ~ Catalina
- Node.js : v10.17.0 (nodebrewでバージョン管理)
- yarn : v1.19.1 (brewでインストール)
- Vue CLI : v3.12.1 (globalにインストール)
- Firebase CLI : v7.8.1 (globalにインストール)
■ 初期設定
社内の勉強会で使用した資料ですが、下記を参考に初期設定。
■ Firebaseパッケージをインストール
# firebaseパッケージをインストール
$ yarn add firebase
# authとか使うときに便利らしいのでとりあえずいれる
$ yarn add firebaseui
■ Firebaseパッケージをインポートする
import firebase from "firebase/app";
import "firebase/firestore";
import "firebase/storage";
import "firebase/auth";
// ↓は各自異なる値になると思います
const firebaseConfig = {
apiKey: "hogehoge",
authDomain: "hoge.firebaseapp.com",
databaseURL: "https://hoge.firebaseio.com",
projectId: "hoge",
storageBucket: "hoge.appspot.com",
messagingSenderId: "123456789",
appId: "hogefuga"
};
export default firebase.initializeApp(firebaseConfig);
// initializeしたものをimportする
import firebase from "@/plugins/firebaseConfig";
export default firebase.firestore();
// initializeしたものをimportする
import firebase from "@/plugins/firebaseConfig";
export default firebase.storage();
● Firestoreを試す
あくまでサンプルなので、誰でも全件データが編集削除できるザル仕様になってます。
コード自体も簡略化していますので、そのままだと動かない可能性が・・・
■ Create
<template>
<div class="create">
<input v-model="inputData.name" type="text">
<button @click="create">送信</button>
</div>
</template>
<script>
import Firebase from 'firebase/app'
import db from '@/plugins/firestore'
export default {
data () {
return {
inputData: {
name: '',
}
}
},
methods: {
create () {
db.collection('records')
.add({
name: this.inputData.name,
createBy: this.$store.state.user.uid,
createAt: Firebase.firestore.Timestamp.now(),
updateAt: Firebase.firestore.Timestamp.now()
})
.then(docRef => {
alert(`Document written with ID: ${docRef.id}`);
})
.catch(error => {
alert(`Error adding document: ${error}`);
});
}
}
}
</script>
■ Read
<template>
<div class="read">
<ul>
<li v-for="(record, index) in records" :key="index">
{{ record.data.name }}
</li>
</ul>
</div>
</template>
<script>
import Firebase from 'firebase/app'
import db from '@/plugins/firestore'
export default {
data () {
return {
records:[]
}
},
methods: {
read () {
// とりあえず全件取得。
db.collection('records')
.get()
.then(querySnapshot => {
querySnapshot.forEach(doc => {
this.records.push({
id: doc.id,
data: doc.data()
})
})
})
}
},
created () {
this.read()
}
}
</script>
↓取得条件を含めるとこんな感じで書けるらしい。
<script>
// 前略
read () {
db.collection('records')
.where('createBy', '==', this.$store.state.user.uid)
.then(querySnapshot => {
querySnapshot.forEach(doc => {
this.records.push({
id: doc.id,
data: doc.data()
})
})
})
}
// 後略
</script>
■ Update
<template>
<div class="update">
<input v-model="recordId" type="text">
<input v-model="editedData.name" type="text">
<button @click="delete">更新</button>
</div>
</template>
<script>
import Firebase from "firebase/app";
import db from "@/plugins/firestore";
export default {
data () {
return {
recordId: 'hoge',
editedData: {
name: '',
updateAt: Firebase.firestore.Timestamp.now()
}
}
},
methods: {
// 指定されたIDのdataを更新する
update () {
db.collection('records')
.doc(this.recordId)
.update(this.editedData)
.then(() => {
alert('Document successfully updated!')
})
.catch(error => {
console.log('Error updating document: ', error)
})
}
}
}
</script>
■ Delete
<template>
<div class="delete">
<input v-model="recordId" type="text">
<button @click="delete">削除</button>
</div>
</template>
<script>
import Firebase from 'firebase/app'
import db from '@/plugins/firestore'
export default {
data () {
return {
recordId: 'hoge',
}
},
methods: {
// 指定されたIDのdataを削除する(物理削除)
delete () {
db.collection('records')
.doc(this.recordId)
.delete()
.then(() => {
alert('Document successfully deleted!');
})
.catch(error => {
console.log('Error removing document: ', error)
})
}
}
}
</script>
おまけ
Cloud Storage
も主題として書きたかったのですが、Update,Delete機能が間に合いませんでした。
でも折角なので載せておきます
■ Create
<template>
<div class="createStorage">
<input type="file" @change="onFileChange">
<button @click="fileSubmit()">登録</button>
</div>
</template>
<script>
import storage from '@/plugins/cloudStorage'
import db from '@/plugins/firestore'
export default {
data () {
return {
// uploadするファイルを格納
file: [],
// 登録用meta情報
submitData: {
filePath: '',
createBy: this.$store.state.user.uid
},
}
},
methods: {
onFileChange() {
this.submitData.filePath = this.file.name;
},
fileInfoRegister(meta_data) {
db.collection('meta')
.add(meta_data)
.then(docRef => {
console.log(docRef)
})
.catch(error => {
console.log(error)
});
},
fileSubmit() {
if (this.file.name) {
// storageのrootディレクトリにファイルを保存する想定
storage.ref()
.child(`${this.submitData.filePath}`)
.put(this.file)
.then(snapshot => {
console.log(`Uploaded a file: ${snapshot.metadata.fullPath}`)
})
.catch(error => {
console.error(`${error.code}:${error.message}`)
})
this.fileInfoRegister(this.submitData)
this.submitData = {}
}
}
},
}
}
</script>
■ Read
<template>
<div class="readStorage">
<ul>
<li v-for="(refImgUrl, index) in refImgUrls" :key="index">
<img :src="refImgUrl">
</li>
</ul>
</div>
</template>
<script>
import storage from '@/plugins/cloudStorage'
import db from '@/plugins/firestore'
export default {
data () {
return {
// dbから取得したもの
getImgUrls: [],
// storageからrefで取得したもの
refImgUrls: [],
}
},
methods: {
fileRead () {
db.collection('meta')
.where('createBy', '==', this.$store.state.user.uid)
.then(querySnapshot => {
querySnapshot.forEach(doc => {
this.getImgUrls.push({
id: doc.id,
data: `${doc.data().parentDir}${doc.data().fileName}`
})
})
this.getImgUrls.forEach(ref => {
storage
.ref()
.child(ref.data)
.getDownloadURL()
.then(url => {
this.refImgUrls.push(url)
})
.catch(error => {
console.log(error)
})
})
})
}
}
created() {
this.fileRead()
},
}
</script>
あとがき
FirebaseはJSが読み書きできれば、自分のアイディアを形にできるので触っていてとても楽しいです。
デメリットがあるとすれば、各種rulesファイルの書き方が独特だということでしょうかね。
ちなみにサンプルコードはテストモードで動かしてますので、権限周りのルールは本当にザルです。
今回は題材をFirestoreに絞りましたが、
Cloud Storage
のリベンジと Firebase Authentication
での権限設定
Cloud Functions + Firebase Admin SDK
で通知設定なども機会があれば記事を書いて見ようかと思います。