Yuta-Fukuhara

喫煙所サーチ (Smoking Area Search)

Next.js / Firebase / Leaflet
喫煙所サーチ

はじめに

喫煙者にとって、外出先で喫煙所を探すのは意外と大変です。そこで、誰でも喫煙所の位置情報を地図上で確認・共有できるWebアプリ「喫煙所サーチ」を開発しました。

この記事では、Next.js、Firebase、Leaflet.jsを使ったアプリケーション開発の過程と、実装した主要機能について紹介します。

アプリの概要

喫煙所サーチは、地図ベースで喫煙所の位置情報を検索・共有できるコミュニティ型のWebアプリケーションです。

主な機能

  • 📍 地図上での喫煙所検索: OpenStreetMapベースの地図で、現在地周辺の喫煙所を表示
  • 喫煙所の新規追加: ユーザーが自由に喫煙所の位置情報を投稿可能
  • 🎯 直感的なUI: 地図中心にピンを合わせて位置を指定する、モバイルフレンドリーな操作性
  • 🔐 ユーザー認証: Firebaseによる安全な認証システム
  • 📱 レスポンシブデザイン: PC・スマートフォンの両方で快適に利用可能
  • 📝 メモ機能: 各喫煙所に「屋外」「灰皿あり」などの補足情報を追加可能

技術スタック

フロントエンド

  • Next.js 14 (App Router)
  • TypeScript: 型安全性を確保
  • Tailwind CSS: スタイリング
  • React Leaflet: 地図表示

バックエンド・インフラ

  • Firebase Firestore / Auth
  • Vercel: デプロイ
  • Docker: 開発環境

開発のポイント

1. 地図のビューポートベース取得による最適化

当初は全ての喫煙所データを一度に取得していましたが、Firebaseの無料枠を考慮して、表示中の地図範囲(ビューポート)内のデータのみを取得する仕組みに変更しました。

// 緯度範囲でフィルタリングし、経度はクライアント側でフィルタ const q = query( collection(db, SMOKING_AREAS_COLLECTION), where('latitude', '>=', minLat), where('latitude', '<=', maxLat) );

これにより、読み取り回数を大幅に削減し、コストを抑えつつパフォーマンスも向上しました。

2. 直感的な位置指定UI

従来の「地図をクリックして位置を指定」方式から、地図中央に固定されたピンに合わせて地図を動かす方式に変更しました。

  • モバイルでの操作性が大幅に向上
  • タップした位置と実際の選択位置のズレを解消
  • より正確な位置指定が可能に

3. セキュリティとプライバシー

  • 利用規約・プライバシーポリシーを整備
  • 投稿時の注意事項表示
  • Firebaseのセキュリティルールによるデータ保護

技術的な課題と解決策

課題1: Firestoreの複合クエリ制約

Firestoreでは、複数の範囲フィルタ(緯度と経度の両方)を同時に使用できません。

解決策: サーバー側(Firestore)で緯度の範囲で絞り込み、クライアント側(JavaScript)で経度でフィルタリングを行いました。これにより、複合インデックス不要で効率的にデータを取得できました。

課題2: SSRとLeafletの互換性

LeafletはブラウザのDOM APIに依存するため、Next.jsのSSRと相性が悪い問題がありました。

解決策: next/dynamic を使用してSSRを無効化しました。

const MapComponent = dynamic(() => import('@/components/MapComponent'), { ssr: false, });

まとめ

Next.js、Firebase、Leaflet.jsを組み合わせることで、ユーザーフレンドリーな位置情報共有アプリを構築できました。 特に、ビューポートベースのデータ取得によるパフォーマンス最適化や、モバイルファーストなUX設計は大きな学びとなりました。