このページの本文へ

FIXER cloud.config Tech Blog

Firebase Javascript SDK v8→v9のFireStore取扱書 in Nuxt × TypeScript

2021年11月26日 11時00分更新

文● 小寺/FIXER

  • この記事をはてなブックマークに追加
  • 本文印刷

 本記事は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’

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’

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.

rameter ‘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

カテゴリートップへ