coiai Logo
Featured

Flutter Webでの Firebase API Key の読み込み クロスプラットフォーム対応

Flutter でWebで動作させる場合にAPI Keyを直書きしない方法について解説します。

通常 index.html にそのまま書けば動作します。

<body>
  <script src="flutter_bootstrap.js" async></script>
  <script>
    const apiKey = "{{API_KEY}}"; // Dartコードで置換
    const script = document.createElement('script');
    script.src = `https://maps.googleapis.com/maps/api/js?key=ここにAPI KEYベタ打ち`;
    document.head.appendChild(script);
  </script>
</body>

しかしこれだと、Gitなどでの管理ができなくなってしまうため、.env ファイルから読み出したいところです。しかしindex.html から直接.env を参照することはできません。

解決方法

プラットフォームごとの処理を追加

Web の場合は以下のファイルを読み込むようにします。 lib の直下に utils ディレクトリを作成し、web_utils.dart を作成しました。

このようにファイルを分けることで、
import ‘dart:html’ as html;
が使えるようになります。

このパッケージはWebのみで動作するため、他のプラットフォームのコードに含められないからです。

// ignore: avoid_web_libraries_in_flutter
import 'dart:html' as html;

void addGoogleMapsScript(String apiKey) {
  final script = html.ScriptElement()
    ..src = 'https://maps.googleapis.com/maps/api/js?key=$apiKey&callback=initMap'
    ..type = 'text/javascript'
    ..async = true
    ..defer = true;
  html.document.body!.append(script);
}

Web 以外(iOS, Android)の場合の処理を書いたファイルも用意します。utils ディレクトリに stub_utils.dart を作成。以下のように書きました。

void addGoogleMapsScript(String apiKey) {
  // モバイルプラットフォームでは何もしない
}

main.dart での処理

flutter_dotenv パッケージを追加します。

flutter pub add flutter_dotenv
import 'package:flutter/material.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'firebase_options.dart';
import 'widgets/bottom_nav_layout.dart';
import 'package:flutter/foundation.dart' show kIsWeb;

// 条件付きインポート
import 'utils/web_utils.dart'
  if (dart.library.html) 'utils/web_utils.dart'
  if (dart.library.io) 'utils/stub_utils.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  
  // 環境変数を読み込む
  await dotenv.load(fileName: ".env");

  // Firebaseの初期化
  await Firebase.initializeApp(
    options: DefaultFirebaseOptions.currentPlatform,
  );

  // Webの場合のみGoogle Mapsスクリプトを追加
  if (kIsWeb) {
    final apiKey = dotenv.env['GOOGLE_MAPS_API_KEY'];
    if (apiKey != null && apiKey.isNotEmpty) {
      addGoogleMapsScript(apiKey);
    } else {
      print('Error: GOOGLE_MAPS_API_KEY is not set in the .env file.');
    }
  }

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Anonymous Login Demo',
      theme: ThemeData(
        useMaterial3: true,
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepOrange),
      ),
      home: const BottomNavLayout(currentIndex: 0),
    );
  }
}

firebase console で web を追加

firebase console でモバイルだけでなく、webを追加して、apikey を発行しましょう。

これを.envに追加します。

.evn ファイルの設定

以下のように設定します。
api_key_here のところで先ほど設定したapi key を入力しましょう。

GOOGLE_MAPS_API_KEY=your_google_maps_api_key_here

# Firebase iOS Configuration
FIREBASE_IOS_API_KEY=your_firebase_ios_api_key_here
FIREBASE_IOS_APP_ID=your_firebase_ios_app_id_here
FIREBASE_IOS_MESSAGING_SENDER_ID=your_firebase_ios_messaging_sender_id_here
FIREBASE_IOS_PROJECT_ID=your_firebase_ios_project_id_here
FIREBASE_IOS_STORAGE_BUCKET=your_firebase_ios_storage_bucket_here
FIREBASE_IOS_BUNDLE_ID=your_firebase_ios_bundle_id_here

# Firebase Web Configuration
FIREBASE_WEB_API_KEY=your_firebase_web_api_key_here
FIREBASE_WEB_AUTH_DOMAIN=your_firebase_web_auth_domain_here
FIREBASE_WEB_PROJECT_ID=your_firebase_web_project_id_here
FIREBASE_WEB_STORAGE_BUCKET=your_firebase_web_storage_bucket_here
FIREBASE_WEB_MESSAGING_SENDER_ID=your_firebase_web_messaging_sender_id_here
FIREBASE_WEB_APP_ID=your_firebase_web_app_id_here
FIREBASE_WEB_MEASUREMENT_ID=your_firebase_web_measurement_id_here

firebase の設定 firebase_options.dart

プラットフォームごとに api key を切り分けるのに使います。

import 'package:firebase_core/firebase_core.dart' show FirebaseOptions;
import 'package:flutter/foundation.dart' show defaultTargetPlatform, kIsWeb, TargetPlatform;
import 'package:flutter_dotenv/flutter_dotenv.dart';

/// Default [FirebaseOptions] for use with your Firebase apps.
class DefaultFirebaseOptions {
  static FirebaseOptions get currentPlatform {
    if (kIsWeb) {
      return web;
    }
    switch (defaultTargetPlatform) {
      case TargetPlatform.android:
        throw UnsupportedError('DefaultFirebaseOptions have not been configured for android.');
      case TargetPlatform.iOS:
        return ios;
      case TargetPlatform.macOS:
        throw UnsupportedError('DefaultFirebaseOptions have not been configured for macos.');
      case TargetPlatform.windows:
        throw UnsupportedError('DefaultFirebaseOptions have not been configured for windows.');
      case TargetPlatform.linux:
        throw UnsupportedError('DefaultFirebaseOptions have not been configured for linux.');
      default:
        throw UnsupportedError('DefaultFirebaseOptions are not supported for this platform.');
    }
  }

  static final FirebaseOptions ios = FirebaseOptions(
    apiKey: dotenv.env['FIREBASE_IOS_API_KEY']!,
    appId: dotenv.env['FIREBASE_IOS_APP_ID']!,
    messagingSenderId: dotenv.env['FIREBASE_IOS_MESSAGING_SENDER_ID']!,
    projectId: dotenv.env['FIREBASE_IOS_PROJECT_ID']!,
    storageBucket: dotenv.env['FIREBASE_IOS_STORAGE_BUCKET']!,
    iosBundleId: dotenv.env['FIREBASE_IOS_BUNDLE_ID']!,
  );

  static final FirebaseOptions web = FirebaseOptions(
    apiKey: dotenv.env['FIREBASE_WEB_API_KEY']!,
    authDomain: dotenv.env['FIREBASE_WEB_AUTH_DOMAIN']!,
    projectId: dotenv.env['FIREBASE_WEB_PROJECT_ID']!,
    storageBucket: dotenv.env['FIREBASE_WEB_STORAGE_BUCKET']!,
    messagingSenderId: dotenv.env['FIREBASE_WEB_MESSAGING_SENDER_ID']!,
    appId: dotenv.env['FIREBASE_WEB_APP_ID']!,
    measurementId: dotenv.env['FIREBASE_WEB_MEASUREMENT_ID'],
  );
}

投稿日: 2025年2月4日
カテゴリ: Flutter
タグ: apple, iOS, web, プログラミング
coiai

coiai

この記事もおすすめ

ポッドキャストを取った後Auditionですべきこと

ポッドキャストを取った後Auditionですべきこと

この記事はポッドキャストなどの音声コンテンツを取った後にAuditionで編集する方法について解説しています。 環境 やること 基本的に以下の4つの工程をすると、かなりクオリティアップにつながります! ノイズリダクション 無音部分を選択します。開始地点をi, 終わりをo キーを押すと選択できます。選択できたらエフェクト→ノイズリダクション/リストア→ノイズプリントをキャプチャを押します。 続いて、全体を選択します。cmd, a で全選択になります。エフェクト→ノイズリダクション/リストア→ノイズリダクションを選択します。 以下のようなパネルが表示されうので、ノイズのみをきたりして、削減ちを調整して、良い感じになったら適応ボタンを押します。 シングルバンドコンプレッサ 左のパネルのエフェクトトラックから▶️ボタンを押し、振幅と圧縮→シングルバンドコンプレッッサを選択します。 選択すると下記のようなパネルが開きます。それぞれ、 といった意味があります。設定値は下記画像のようにしています。 設定がめんどくさい場合はプリセットからラジオレベラーを選択してください。 EQ(声をクリアにする) パラメトリックイコライザーを使用します。エフェクト→フィルターとイコライザ→パラメトリックイコライザーを選択します。 私の場合は下記のように設定しています。 無音カット エフェクト→診断→無音をカットをすると左パネルに診断が表示されます。 効果を無音を削除、プリセットをポッドキャストにするとちょうどよくなると思います。設定したら、スキャンボタンを教えて、全て削除で無音がカットされます。 かなりカットされてしまうので、短いCM等に使うのはありかなという感じです。 参考 Adobe 無音カット https://helpx.adobe.com/jp/audition/using/strip-silence.html

この記事を書いた会社

株式会社coiaiは、「想像できることを美しく実現」を掲げ、XR・Web・アプリ・システム開発およびDX支援を行う会社です。 創業2022年、東京都練馬区に本社を置き、要件のヒアリングからPoC(概念実証)、本番運用まで一貫して伴走します。 まずはお気軽にご相談ください。

商号株式会社 coiai創業2022年1月設立2025年1月23日資本金1,500,000円(設立時点)本社所在地東京都練馬区関町北 3-6-9代表者代表取締役 竹村 啓佑 / 代表取締役 服部 陽良

主なご相談内容

会社概要・役員紹介を見る

詳しい会社情報は会社概要ページでご覧いただけます。

資料請求・無料相談

導入要件のヒアリングからPoC、本番運用まで伴走します。まずはお気軽にご相談ください。

お問い合わせの前に 個人情報保護方針 をご確認ください。