FirebaseによるカスタムEコマース構築

ゼロからカスタムEコマースサイトを構築しました。既存のプラットフォームは使用せず、代わりにFirebase Realtime DatabaseとNetlifyを使用しました。

クライアントには特定のセットアップが必要でした。価格バリエーションを持つ商品カタログと管理パネルが求められていました。また、営業チームがサイトから直接注文を行えるようにする必要もありました。

主な技術的課題をどのように解決したかを以下に示します。

データの分離

Eコマース用のデータベースを内部管理用のデータベースとは別にしました。これにより、商用データが従業員の給与や予算などの機密ファイルと混ざるのを防いでいます。

価格設定のためのデータモデリング

価格プランは、異なる製品間で重複することがよくあります。すべての製品内にプランデータを複製してしまうと、更新作業が非常に困難になります。

  • すべてのプランのためのグローバルアーカイブを作成しました。
  • 各製品はプランIDの配列のみを保持します。
  • これにより、更新が迅速になり、データエラーを防ぐことができます。

アトミックな注文番号の発行

複数のユーザーが同時に注文を行うと、レースコンディション(競合状態)が発生します。2人のユーザーが同じ最新の注文番号を読み取ってしまうと、一方の注文が上書きされてしまいます。

  • これを解決するためにFirebaseのトランザクションを使用しました。
  • runTransaction 関数を使用することで、多くのユーザーが同時にアクセスしても、番号が正しくインクリメントされることを保証します。
  • これにより、すべての注文に一意の番号が割り当てられることが保証されます。

安全な管理者アクセス

ソースコード内にパスワードを保存したくありませんでした。また、MD5のような単純なハッシュ化も避けました。

  • Web Crypto APIを介してPBKDF2を使用しました。
  • これにより、ハッシュに対して数千回の反復処理が行われます。
  • これにより、ハッカーにとってブルートフォース攻撃のコストが非常に高くなります。
  • コード内にはソルトとハッシュのみを保存しています。

「ゼロ」バグの修正

価格が0の製品が「価格未定(price to be defined)」と表示されるバグを発見しました。

  • これは、JavaScriptが0を「falsy(偽値)」として扱うために起こりました。
  • ロジックを変更することでこれを修正しました。
  • "price || null" を使う代わりに "price != null" を使用しました。
  • これにより、システムが0を有効な数値として認識できるようになります。

CSPの設定

Firebaseは動的なサブドメインを使用します。Content Security Policy (CSP) 用の標準的なHTMLメタタグでは、これらのワイルドカードを扱うことができません。

  • CSPをHTMLからNetlifyのHTTPヘッダーに移動しました。
  • これにより、Firebaseのサービスが正しく動作するようにワイルドカードを使用できるようになりました。

カスタムシステムの構築には、単にコードを書くだけでは不十分です。本番環境での障害を防ぐためのアーキテクチャ上の選択が求められます。

出典: https://dev.to/androve2k/custom-e-commerce-on-firebase-catalog-atomic-orders-and-admin-panel-42ec