FIXER cloud.config Tech Blog
Firebase Javascript SDK v8→v9のFireStore取扱書 in Nuxt × TypeScript
2021年11月26日 11時00分更新
本記事はFIXERが提供する「cloud.config Tech Blog」に掲載された「Firebase Javascript SDK v8→v9 のFireStore取扱書 in Nuxt × TypeScript」を再編集したものです。
はじめに
8月下旬、Firebase JavaScript SDK v9がリリースされました。
自分のポートフォリオサイトはFirebaseを利用していたのでv9へアップデートしたのですが、記法に互換性がなくなっていた影響で素直にアップデートするだけではダメでした。
そこで、v8、v9それぞれの記法の違いを簡単にまとめようと思います。
その際に遭遇した型エラーもこちらへ残します。
※ 今回はCloud FireStoreに触れます
対象者
・Nuxt.jsでFirebaseのFireStoreを利用している方
・Firebase Javascript SDK v8 → v9にアップデートしたい方
・FireStoreに型を付けたい方
・🐭 !!🐮 !!🐯 🐰 🐲 🐍 🐴 🐏 🐵 🐔 🐶 🐗
筆者の環境
・Node.js (14.18.0)
・yarn (1.22.4)
・Firebase (9.1.3)
・TypeScript (4.2.4)
・VScode(1.60.0)
・Nuxtは2系です
まずはFirebase初期化部分から
■v8 SDK
Firebase JavaScript SDK v8の詳しい導入方法はこちらに記載されています。
公式が「v9 SDK を使用することを強くおすすめします。」と言っているので特別な理由がない限りは、v9を利用した方がいいみたいです。
plugin/firebase.ts
// v8
import firebase from 'firebase/app';
if (!firebase.apps.length) {
firebase.initializeApp({/* config */});
}
export default firebase;
上記補足として、以下のエラーが発生することがあったので
Bash
Firebase: Firebase App named '[DEFAULT]' already exists
対処として
plugin/firebase.ts
if (!firebase.apps.length) {
...
}
で囲ってエラー回避していました。
■v9 SDK
import周りが変わっています。
利用するやつのみimportすることによってコンパイル時のアプリサイズを削減できるのが売りらしいです。
📦新しいモジュラーJavaScriptSDKは、アプリバンドルを最大80%小さくすることができます。JavaScript SDKのバージョン9は、バンドラーが未使用のコードを排除し、JavaScriptバンドルのFirebaseライブラリコードを最大80%削減できるモジュールファーストフォーマットを採用しています。
configに型が用意されていたので早速使っています。
plugin/firebase.ts
// 必要なもののみimport
import { FirebaseOptions, getApps, getApp, initializeApp, FirebaseApp } from 'firebase/app';
const firebaseConfig: FirebaseOptions = {/* config */};
const firebase: FirebaseApp = !getApps().length ? initializeApp(firebaseConfig) : getApp();
export default firebase;
v8の時に発生したエラーはv9では!getApps().lengthを利用した分岐で回避するようにしました。
Cloud FireStoreを利用する側
ここでは、データ取得、 データ追加周りv8とv9 の時の記法をそれぞれご紹介します。
必要な部分のみ抜粋しています。
■データ取得
はじめにデータ取得の実装周りです。
取得部分は今回created内に書いていますが、あくまで記事用なのでcreated内に書く特別な意図はありません。
□v8 SDK
firebase/firestoreはまるまるimportしています。
index.vue
// v8
<script lang="ts">
import firebase from '~/plugins/firebase';
import 'firebase/firestore';
export default Vue.extend({
created () {
const db: firebase.firestore.Firestore = firebase.firestore(); // Firestore のインスタンスを初期化
if (!db) { return; }
db.collection('hoge').get()
.then((querySnapshot) => {
querySnapshot.forEach((doc: firebase.firestore.QueryDocumentSnapshot) => {
...
});
});
}
})
□v9 SDK
firestoreは必要な部分のみimportするようになりました。
記法が変わり、getDocsという取得用の新しい関数が登場しました。
また、型定義も変わっています。
index.vue
// v9
<script lang="ts">
import firebase from '~/plugins/firebase';
import { Firestore, getFirestore, getDocs, collection, QueryDocumentSnapshot } from 'firebase/firestore';
export default Vue.extend({
created () {
const db: Firestore = getFirestore(firebaseApp); // Firestore のインスタンスを初期化
if (!db) { return; }
getDocs(collection(db, 'hoge'))
.then((querySnapshot) => {
querySnapshot.forEach((doc: QueryDocumentSnapshot) => {
...
});
});
}
})
■データ追加
続いてデータ追加の実装周りです。
□v8 SDK
index.vue
// v8
<script lang="ts">
import firebase from '~/plugins/firebase';
import 'firebase/firestore';
export default Vue.extend({
methods: {
addData () {
const db: Firestore = getFirestore(firebaseApp);
db.collection("hoge").add({
name: "deren",
country: "Japan"
});
}
}
})
□v9 SDK
こちらも記法が変わり、 addDoc というデータ追加用の新しい関数が登場しました。
index.vue
// v9
<script lang="ts">
import firebase from '~/plugins/firebase';
import { Firestore, getFirestore, addDoc, collection } from 'firebase/firestore';
export default Vue.extend({
methods: {
addData () {
const db: Firestore = getFirestore(firebaseApp);
await addDoc(collection(db, 'hoge'), {
name: 'deren',
country: 'Japan'
});
}
}
})
v8 → v9にアップデートした際の型エラー
互換性がなくなった影響で、v8 → v9へアップデートした際に型エラーがちらほら発生しました。
以下に記載する私が遭遇したエラーはこの記事で解消できるものなので、似たようなエラーに遭遇してしまったらこの記事を参考にしていただけると嬉しいです。
■Cannot find namespace ‘firebase’
index.vue
// v8
const db: firebase.firestore.Firestore = firebase.firestore();
// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// v9
const db: Firestore = getFirestore(firebaseApp);
※ 型は firebase/firestoreからimportしてください
■Property ‘firestore’ does not exist on type ‘FirebaseApp’
index.vue
// v8
const db: firebase.firestore.Firestore = firebase.firestore();
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// v9
const db: Firestore = getFirestore(firebaseApp);
※ 型は firebase/firestoreからimportしてください
■Parameter ‘querySnapshot’ implicitly has an ‘any’ type.
index.vue
// v8
await this.db.collection('hoge').get()
.then((querySnapshot) => {
querySnapshot.forEach((doc: firebase.firestore.QueryDocumentSnapshot) => {
...
});
})
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
// v9
await getDocs(collection(this.db, 'hoge'))
.then((querySnapshot) => {
querySnapshot.forEach((doc: QueryDocumentSnapshot) => {
...
});
})
※ 型は firebase/firestoreからimportしてください
参考
・Firebase を JavaScriptプロジェクトに追加する
・Cloud Firestoreを使ってみる
小寺/FIXER
みならいフロントエンジニアのデレンが勝負をしかけてきた!
[転載元]
Firebase Javascript SDK v8→v9 のFireStore取扱書 in Nuxt × TypeScript