0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

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

Last updated at Posted at 2021-11-11

はじめに

Firebase Javascript SDK v8とv9では記法に互換性がなくなってしまいました。
そのため、素直にv8 SDK→v9 SDKとアップデートするだけでは動かなくなってしまったので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 SDKを利用した方がいいみたいです。

plugins/firebase.ts
// v8
import firebase from 'firebase/app';

if (!firebase.apps.length) {
  firebase.initializeApp({/* config */});
}

export default firebase;


上記補足として、以下のエラーが発生することがあったので

Firebase: Firebase App named '[DEFAULT]' already exists

対処として

plugins/firebase.ts
if (!firebase.apps.length){ 
  ...
}

で囲ってエラー回避していました。

v9 SDK

import 周りが変わっています。
利用するやつのみ import することによってコンパイル時のアプリサイズを削減できるのが売りらしいです。

当時のリリースノート

📦新しいモジュラーJavaScriptSDKは、アプリバンドルを最大80%小さくすることができますJavaScript SDKのバージョン9は、バンドラーが未使用のコードを排除し、JavaScriptバンドルのFirebaseライブラリコードを最大80%削減できるモジュールファーストフォーマットを採用しています。

configに型が用意されていたので早速使っています。

plugins/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しています。

// 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 という取得用の新しい関数が登場しました。
また、型定義も変わっています。

// v9
<script lang="ts">
import firebaseApp 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

// v8
<script lang="ts">
import firebaseApp 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 というデータ追加用の新しい関数が登場しました。

// v9
<script lang="ts">
import firebaseApp 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 SDK → v9 SDKにアップデートした際の型エラー

互換性がなくなった影響で、v8 SDK → v9 SDK へアップデートした際に型エラーがちらほら発生しました。
以下に記載する私が遭遇したエラーはこの記事で解消できるものなので、似たようなエラーに遭遇してしまったらこの記事を参考にしていただけると嬉しいです。

Cannot find namespace 'firebase'

スクリーンショット 2021-11-11 20.13.48.png

// 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'

スクリーンショット 2021-11-11 20.15.44.png

// v8
const db: firebase.firestore.Firestore = firebase.firestore(); 

// ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

// v9
const db: Firestore = getFirestore(firebaseApp);

※ 型は firebase/firestore から importしてください

Parameter 'querySnapshot' implicitly has an 'any' type.

スクリーンショット 2021-11-11 20.20.29.png

// 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してください

参考

0
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?