見出し画像

FireBaseの開発で盛大にやらかした話

こんにちは😀

数日前から家計簿のWebアプリ開発に取り掛かっています。
我が家の家計簿はこれまでExcelで非常にアナログだったので、今後ずっと使い続けることを想定して、拡張性が高くスマホからでもアクセスできるようにブラウザベースのアプリケーションで作ろうと思いました🤔
技術スタックは私の中ではお馴染みの下記です!

  • フロントエンド: React+TypeScript

  • バックエンド: Firebase/FireStore

  • CI/CD: GithubActions

しかし、開発中に重大なミスを犯してしまったので、誰かの役に立てば幸いだなーということでここに残しておきます😇😇
それが、

🔥🔥🔥FireStoreの読み取りデータ量を1時間で超えてしまいました🔥🔥🔥

開発中に突然、アカウント認証やデータの読み込み書き込みができなくなってしまい、Firestoreの使用状況を確認しました。

すると。。。。

Firestoreデータ使用量

読み取りに関するクォータ(データ量)が1時間で5.6万に到達してました🙆‍♂️w

開発しているだけでそんなに読み込み書き込みをしている訳ではなかったので、ハッキングを疑いました・・・(アホ)

原因👨‍💻

結論から言うと、データのリアルタイム取得使用していたFirestoreのonSnapShotメソッドが原因でした。
onSnapShotはチャットアプリやTwitterのようにリロードせずともリアルタイムにデータを更新する際に便利なメソッドです。
そのため、今回は家計簿の月次データを取得する際にリアルタイムに反映させたいため、onSnapShotを使用して更新をかけていました。

//onSnapShotメソッドを使用したコード
useEffect(() => {
    if (books.length === 0) {
      // 本のリストが空の場合のみデータを取得
      const unsubscribe = onSnapshot(collection(db, 'books'), (snapshot) => {
        const booksArray: Book[] = []
        snapshot.forEach((doc) => {
          booksArray.push({ id: doc.id, ...doc.data() })
        })
        setBooks(booksArray)
      })

      return () => unsubscribe()
    }
  }, [books])

しかし、便利な反面大きなデメリットも存在します。
こちらは何かしらのデータが更新されるたびに処理が発火するため、家計簿の登録、家計簿内で金額の入力、お店の名前を入力、登録日時を登録・・・それを数レコード・・・と繰り返していくと、1つ1つの書き込みが行われる度に発火し、毎回全てのデータを読み取ってしまいます。
そのため、データ量が異常なまでに上がったのかなと推測しました。

解決策🏄‍♂️

onSnapShotメソッドを使用する際にdocChangesメソッドも使用してあげることで、解決ができそうです。
docChangesは登録・追加・削除の変更の差分のみを取得してくるため、クォートが最小限で抑えられるようです。
つまり、onSnapShotと併用して使用することで、差分のみをリアルタイム監視してデータ取得ができるようになります。

useEffect(() => {
    if (books.length === 0) {
      // 本のリストが空の場合のみデータを取得
      const unsubscribe = onSnapshot(collection(db, 'books'), (snapshot) => {
        const booksArray: Book[] = []
        snapshot.onChanges().forEach((doc) => { //ここに.onChanges()を追加!!
          booksArray.push({ id: doc.id, ...doc.data() })
        })
        setBooks(booksArray)
      })

      return () => unsubscribe()
    }
  }, [books])

まとめ🙆‍♂️

今回のクォート爆上げ案件で丸1日開発が出来なくなってしまったので、
Firestoreの無料枠でやられている方はぜひ気をつけてください🥹

では( ^∀^)

この記事が気に入ったらサポートをしてみませんか?