# 【Flutter】FCMとSupabase Edge FunctionsでPush通知〜第1回〜

> FCMとSupabase Edge Functions（database webhook）を使用したPush通知の送信方法について解説。Firebaseの設定からFlutterでの実装、テスト送信までの流れを詳しく紹介します。

- 公開日: 2024-12-05
- 更新日: 2025-06-05
- 著者: Matsu
- タグ: Flutter, Supabase
- URL: https://tech.anycloud.co.jp/articles/push-notification-flutter-supabase-1

---

今回は、FCMとSupabase Edge Functions（database webhook）を使用してPush通知を送信するところまで紹介していきます。

以下の動画を参考にしています。

<iframe src="https://www.youtube.com/embed/CiSv9E6ZKVc?rel=0&amp;cc_load_policy=1" style="top: 0; left: 0; width: 100%; height: 100%; position: absolute; border: 0;" allowfullscreen="" scrolling="no" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share;"></iframe>

## 構成

<figure><img src="./image-001.webp" alt="SuapbaseのPush通知構成" width="2942" height="1506"></figure>

## 開発の流れ

1.  Firebaseの設定
2.  Firebaseの環境分け（devとprod）
3.  FlutterでFirebase初期化を実装
4.  FCMの設定【← 第1回はここまで】
5.  Flutterで通知許可ダイアログを実装
6.  バックグラウンド・フォアグラウンド・ターミネート状態でのPush通知の受信
7.  Firebase Messagingでテスト送信【← 第2回はここまで】
8.  Supabaseインストール
9.  Supabase Edge Functionsの実装
10.  Webhookを設定
11.  SupabaseからFlutterアプリにPush通知を送信【← 第3回はここまで】

## Firebaseの設定

まずはiOSとAndroidのFirebase設定を進めます。

※Firebaseプロジェクトは作成済みの前提です。

<div class="link-card-wrap"><a class="link-card" href="https://firebase.google.com/docs/flutter/setup?hl=ja" target="_blank" rel="noopener noreferrer"><span class="link-card-body"><span class="link-card-title">Flutter アプリに Firebase を追加する</span><span class="link-card-meta"><img class="link-card-favicon" src="./linkcard-01-favicon.webp" alt=""><span class="link-card-domain">firebase.google.com</span></span></span></a></div>

### Firebase にログインとパッケージの追加

```shell
% firebase login
```

コアプラグインをインストールします。

```plaintext
% flutter pub add firebase_core
```

## Firebase を使用するようにdevとprod環境に分けてアプリを構成

Flutter アプリを Firebase に接続するように構成します。

バンドルIDは以下に記載されています。

iOS : `ios/Runner.xcodeproj/project.pbxproj`にある`PRODUCT_BUNDLE_IDENTIFIER`

Android : `android/app/build.gradle`にある`defaultConfig > applicationId`

今回は、環境分けもします。

### iOSのdevとprodの環境を構成

まずは、コマンドで生成。

```plaintext
// dev
% flutterfire configure --project=sample-app-dev --out=lib/firebase_options_dev.dart --platforms=android,ios --ios-bundle-id=jp.co.sample.www.app.sample.dev --android-package-name=jp.co.sample.www.app.dev

// prod
% flutterfire configure --project=sample-app --out=lib/firebase_options.dart --platforms=android,ios --ios-bundle-id=jp.co.sample.www.app.sample --android-package-name=jp.co.sample.www.app
```

`GoogleService-Info.plist`は以下のように分けました。

<figure><img src="./image-002.webp" alt="GoogleService-Info.plistの環境分け" width="300" height="269"></figure>

`Xcode > Runner > Build phase > Run Script`に以下追記して、読み込みファイルを分けます。

注意点として、`Copy Bundle Resouces`より上に持ってくる必要があります。

```swift
if [ "${FLAVOR}" == "dev" ]; then
  cp "${PROJECT_DIR}/Runner/dev/GoogleService-Info.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist"
else
  cp "${PROJECT_DIR}/Runner/prod/GoogleService-Info.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist"
fi
```

<figure><img src="./image-003.webp" alt="Run Script" width="1396" height="352"></figure>

### Androidのdevとprodの環境を構成

`google-service.json`ファイルは以下のように分けておきます。

<figure><img src="./image-004.webp" alt="" width="296" height="265"></figure>

`android/setting.gradle`に以下追記。

```shell
plugins {
    ...
    // START: FlutterFire Configuration
    id "com.google.gms.google-services" version "4.3.15" apply false
    // END: FlutterFire Configuration
    ...
}
```

`android/app/build.gradle`に以下追記。

```shell
plugins {
    ....
    id "com.google.gms.google-services"
}
```

ちなみに、Google Servicesプラグイン自体がフレーバーに対応しているみたいです。

つまり、`google-services.json` ファイルをフレーバーごとに配置することで、自動的に設定が選択されます。

そのため、カスタムタスクを作成して`google-services.json`をコピーする必要はありませんでした

<div class="link-card-wrap"><a class="link-card" href="https://firebase.google.com/docs/projects/multiprojects?hl=ja" target="_blank" rel="noopener noreferrer"><span class="link-card-body"><span class="link-card-title">複数のプロジェクトを構成する &nbsp;|&nbsp; Firebase</span><span class="link-card-meta"><img class="link-card-favicon" src="./linkcard-02-favicon.webp" alt=""><span class="link-card-domain">firebase.google.com</span></span></span></a></div>

## FlutterでFirebase初期化

生成されている残りのファイルはこんな感じで分けています。

<figure><img src="./image-005.webp" alt="" width="388" height="224"></figure>

`lib/main.dart` ファイルで、Firebase を初期化します。

```dart
// このあたり良きように追加
WidgetsFlutterBinding.ensureInitialized();

if (Firebase.apps.isEmpty)
  Firebase.initializeApp(
    name: flavor.isDev ? 'sample-app-dev' : 'sample-app',
    options: getFirebaseOptions(),
  ),

FirebaseOptions getFirebaseOptions() {
  switch (flavor) {
    case Flavor.dev:
      return dev.DefaultFirebaseOptions.currentPlatform;
    case Flavor.prod:
      return prod.DefaultFirebaseOptions.currentPlatform;
  }
}

// flavorはすでに用意しているものを使用
final flavor = Flavor.fromEnvironment;

enum Flavor {
  dev,
  prod;

  static Flavor get fromEnvironment {
    const flavor = String.fromEnvironment('FLAVOR');
    return Flavor.values.byName(flavor);
  }

  bool get isDev => name == 'dev';
  bool get isProd => name == 'prod';
}
```

環境分けてfirebaseを使うと以下のようなエラーが起きやすいため、回避するために`initializeApp`で`name`オプションを使用しています。

```shell
Exception: [core/duplicate-app] A Firebase App named "[DEFAULT]" already exists
```

### ビルド用にlaunch.jsonを修正

flavorなどを追加してios、androidともにビルドできるかを確認します。

```json
{
    "name": "Run dev debug",
    "request": "launch",
    "type": "dart",
    "program": "lib/main.dart",
    "flutterMode": "debug",
    "args": [
        "--flavor dev",
        "--dart-define=FLAVOR=dev"
    ]
},
```

pod関連のエラーが出たら、podインストールなどクリーンしましょう。

## FCMの設定

<div class="link-card-wrap"><a class="link-card" href="https://firebase.google.com/docs/cloud-messaging/ios/client?hl=ja" target="_blank" rel="noopener noreferrer"><span class="link-card-body"><span class="link-card-title">Apple プラットフォーム アプリで Firebase Cloud Messaging を使ってみる</span><span class="link-card-description">Apple アプリで Firebase Cloud Messaging を使用する方法について説明します。</span><span class="link-card-meta"><img class="link-card-favicon" src="./linkcard-03-favicon.webp" alt=""><span class="link-card-domain">firebase.google.com</span></span></span></a></div>

<div class="link-card-wrap"><a class="link-card" href="https://firebase.google.com/docs/cloud-messaging/android/client?hl=ja" target="_blank" rel="noopener noreferrer"><span class="link-card-body"><span class="link-card-title">Android アプリで Firebase Cloud Messaging を使ってみる</span><span class="link-card-description">Android アプリで Firebase Cloud Messaging を使用する方法について説明します。</span><span class="link-card-meta"><img class="link-card-favicon" src="./linkcard-04-favicon.webp" alt=""><span class="link-card-domain">firebase.google.com</span></span></span></a></div>

### XcodeでPush NotificationsとBackground Modesを追加

`Xcode > Runner > Signing & Capabilities > + Capability`を選択して、`Push Notifications` と `Background Modes`を追加します。

<figure><img src="./image-006.webp" alt="Push Notifications と Background Modesを追加" width="1384" height="858"></figure>

### APN認証キーを発行

Apple Developerから`Certificates, Identifiers & Profiles`でキーを発行します。

追加できたら忘れずにダウンロードしましょう。

<figure><img src="./image-007.webp" alt="Certificates, Identifiers &amp; Profilesでキーを発行" width="2526" height="1106"></figure>

### Firebase Cloud Messagingにアップロード

プロジェクトの設定からキーをアップロードします。

-   キーファイル
-   キーID : 先ほどAppleで発行したKey ID
-   チームID : Apple developer開いて右上に`会社名 - チームID`で記載されているチームID
    
    <figure><img src="./image-008.webp" alt="Firebase Cloud Messagingにアップロード" width="694" height="224"></figure>
    

<figure><img src="./image-009.webp" alt="Firebase Cloud Messagingにアップロード" width="1262" height="632"></figure>

今回はこれで一旦完了です。

続きは以下の記事を見てください。

<div class="link-card-wrap"><a class="link-card" href="/articles/push-notification-flutter-supabase-2/" target="_blank" rel="noopener noreferrer"><span class="link-card-body"><span class="link-card-title">【Flutter】FCMとSupabase Edge FunctionsでPush通知〜第2回〜</span><span class="link-card-description">Flutterを用いたFCM（Firebase Cloud Messaging）とSupabase Edge FunctionsによるPush通知の実装方法について解説。具体的に通知の許可ダイアログ実装、バックグラウンド・フォアグラウンド状態でのPush通知の受信方法、Firebase Messagingでのテスト送信手順を紹介。</span><span class="link-card-meta"><img class="link-card-favicon" src="./linkcard-05-favicon.ico" alt=""><span class="link-card-domain">tech.anycloud.co.jp</span></span></span><img class="link-card-image" src="./linkcard-05-image.webp" alt=""></a></div>

<div class="link-card-wrap"><a class="link-card" href="/articles/push-notification-flutter-supabase-3/" target="_blank" rel="noopener noreferrer"><span class="link-card-body"><span class="link-card-title">【Flutter】FCMとSupabase Edge FunctionsでPush通知〜第3回〜</span><span class="link-card-description">Flutterを使用してSupabase Edge Functionsを介してPush通知を送信する方法を解説。Firebaseの設定からSupabaseのインストール、Edge Functionsの実装、デプロイまでの流れを紹介します。</span><span class="link-card-meta"><img class="link-card-favicon" src="./linkcard-06-favicon.ico" alt=""><span class="link-card-domain">tech.anycloud.co.jp</span></span></span><img class="link-card-image" src="./linkcard-06-image.webp" alt=""></a></div>
