2
0

More than 1 year has passed since last update.

Firestore Data Bundlesをサーバーサイドから利用することは可能か?

Last updated at Posted at 2022-12-09

はじめに

Firestoreの読み取りコストを削減するための仕組みとして、Firestore Data Bundlesがあります。
基本的にはクライアントのSDK(Webやモバイル)からの利用が想定されていますが、サーバーサイドからも利用することはできないか調査しました。

結論

  • Firestore Data Bundlesはただの静的ファイルなのでサーバーサイドからも読み取ることは可能
  • ただしマッチョな実装になるので少々注意が必要

Firestore Data Bundlesとは

公式ドキュメントもありますが、上記ブログ記事がとても分かりやすいです。
コードと内容ともかなり参考にさせていただきました。

簡単にまとめると、Firestore Data BundlesとはFirestore上の読み取り頻度が高いデータを静的ファイル化しCDN、ホスティング サービス、その他に展開して利用する仕組みです。
クライアントはFirestoreを呼び出さなくてもデータにアクセスできるため、アクセスコストの削減やクエリ結果の高速な読み込みが期待できます。
下記のような流れで処理が進むイメージです。

処理の流れ
1. サーバーサイド: Firestoreデータ読み取り
          ↓
2. サーバーサイド: Bundles形式に変換
          ↓
3. サーバーサイド: 静的ファイル化 ex. txtファイル
          ↓
4. サーバーサイド: CDN、ホスティング サービス、その他にアップロード
          ↓
5. クライアント: 静的ファイルを取得
          ↓
6. クライアント: Bundles形式として読み込み

②の「Bundles形式に変換」についてはNode.jsやJava、PythonのAdmin SDKが対応しています。

Node.jsの場合(公式ドキュメントより引用)
// Build the bundle
// Note how querySnapshot is named "latest-stories-query"
var bundleBuffer = bundle.add(docSnapshot); // Add a document
                   .add('latest-stories-query', querySnapshot) // Add a named query.
                   .build()

⑥の「Bundles形式として読み込み」についてはWebやモバイルのSDKが対応しています。

Webの場合(公式ドキュメントより引用)
await db.loadBundle(resp.body);

Firestore Data Bundles形式のデータは、Firestoreドキュメントの内容と、それらを生成したクエリに関するメタデータの両方が含まれたJSONのような形式です(下記のスクショ。一部黒塗り)。

image.png

サーバーサイドで利用する試み

前述の通り、Firsetore Data Bundlesを読み込んで利用するためのAPI(ex. loadBundle())はWebやモバイルのSDKにしか用意されていません。
しかし、Firestore Data Bundlesはただの静的ファイル(先ほどのスクショの場合はテキストファイル)なので、SDKを利用せずともサーバーサイドでも読み込むことはできそうです。

中身はほぼjsonですが余分な数字が入ってるのと、複数のjsonオブジェクトがちゃんと連結されてないので配列可しました。

上記ブログ記事に記載の通り、Firestore Data Bundlesは余分な数字が入ったJSONといった面持ちで絶妙に取り回しづらくなってはいますが、正規表現等々用いてキレイにしてあげます。

自身の実装より抜粋
var (
	headNumber   = regexp.MustCompile("^[0-9]{3}{")
	middleNumber = regexp.MustCompile("}[0-9]{3}{")
)

func replaceHeadNumber(str string) string {
	return headNumber.ReplaceAllString(str, "[{")
}

func replaceMiddleNumber(str string) string {
	return middleNumber.ReplaceAllString(str, "},{")
}

func bundlesToJSONString(str string) string {
	str = replaceHeadNumber(str)
	return replaceMiddleNumber(str) + "]"
}

func bundlesToJSON(str string) ([]any, error) {
	var ret []any
	formatted := bundlesToJSONString(str)
	if err := json.Unmarshal([]byte(formatted), &ret); err != nil {
		return nil, err
	}
	return ret, nil
}

このようにすれば、サーバーサイドでもFirestore Data Bundlesに含まれるドキュメントにアクセスすることができます。
ただし、あくまでテキストファイルを無理やり読み込んでいるだけなので、例えばFirebase Data Bundlesのデータ仕様が変更になった際には、動かなくなる可能性があります。
フルのコードはこちらに置いています。

終わりに

  • Firestore Data Bundlesをサーバーサイドからも利用することができるか調査しました
  • 結論として、利用は可能ですが、仕様変更にロバストではなく実戦投入には課題が残ります
  • サーバーサイドでFirestoreのコスト削減に挑む場合の方法については今後も模索していきたいです
2
0
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
2
0