---
title: "FCM（Firebase Cloud Messaging）とは｜プッシュ通知の仕組み・送信方法とFID移行【2026年10月時点】"
url: "https://www.issoh.co.jp/tech/details/3448/"
published: 2024-09-03
updated: 2026-10-23
categories: ["Firebase"]
publisher: "株式会社一創"
---

# FCM（Firebase Cloud Messaging）とは｜プッシュ通知の仕組み・送信方法とFID移行【2026年10月時点】

FCM（Firebase Cloud Messaging）は、Googleが提供するプッシュ通知の配信基盤です。自社のサーバーからAndroid・iOS・Webのアプリへメッセージを送れて、料金はかかりません。自動車の「FCM（衝突被害軽減ブレーキ）」とは無関係で、この記事ではアプリ開発のFCMだけを扱います。

2026年はFCMの仕様が大きく動いた年です。端末を指す宛先は、従来の「登録トークン」からFirebase Installation ID（FID）へ移行中です。9月には旧来のサーバーAPI群とデバイスグループ機能が非推奨になり、2027年9月29日に停止すると告知されました。10月7日には各SDKのメジャー更新もありました。この記事では、FCMの定義と配信の仕組み、メッセージの種類、HTTP v1 APIとAdmin SDKの送信コード、停止までに移行すべきAPI、送信上限、通知が届かないときの確認点を、2026年10月23日時点の公式ドキュメントに沿って説明します。

## まとめ：FCMの要点と2026〜2027年の変更点

- FCMは、送信側（自社サーバーかCloud Functions）と受信側（Android・Apple・Webのアプリ）で構成されるクロスプラットフォームの配信基盤。Firebaseの料金表では「No-cost」で、費用がかかるのは送信処理を載せるサーバーやCloud Functionsの側。
- メッセージは、OSが自動で表示する「通知メッセージ」と、アプリのコードが処理する「データメッセージ」の2種類。1通のペイロードは4096バイトまで。
- サーバーからの送信はHTTP v1 APIかFirebase Admin SDKで行う。サーバーキーを使う旧APIは2024年7月22日から段階的に停止済み。
- 宛先IDは登録トークンからFIDへ移行中。Android SDK 25.1.0・iOS SDK 12.18.0・Node.js版Admin SDK 14.1.0以降でFIDを使える。移行期間中はどちらの宛先でも送れる。
- Instance IDのサーバーAPI（旧トピック購読・トークン情報の取得など）とデバイスグループは2027年9月29日に停止する。新規の利用開始は、デバイスグループが2026年12月1日、Instance IDのAPIが2027年1月1日で締め切られる。トピック購読をAdmin SDKで行っているなら、Node.js 14.5.0・Python 7.7.0・Java 9.11.0・Go 4.22.0・.NET 3.7.0以上へ上げる。
- 2026年10月のメジャー更新で、Android版firebase-messaging 26系はminSdk 24（Android 7.0）以上、Apple SDK 13系はiOS 15.0以上が必須になった。
- 送信APIの成功は「受け付けた」という意味で、端末に届いた証明ではない。届かないときは、宛先の失効、通知権限、省電力、フォアグラウンド時の処理、社内ネットワークのポート制限の順に確かめる。

## FCMとは：Firebase Cloud Messagingの定義・対応環境・GCMの経緯

Firebase Cloud Messagingとは、公式の[Firebase Cloud Messagingの概要ページ](https://firebase.google.com/docs/cloud-messaging)で「メッセージを確実に送れるクロスプラットフォームのメッセージング手段」と定義されているサービスです。Firebaseという開発プラットフォームを構成する製品の1つで、認証やデータベースなど他のFirebase製品を使っていなくても、FCMだけを単独で使えます。使い始めるにはFirebaseプロジェクトを作り、アプリを登録してSDKを入れる作業が要ります。共通の手順は[Firebaseの導入手順（プロジェクト作成からSDK導入まで）](/tech/details/16678/)で説明しています。

公式の概要ページによると、FCMの実装は2つの部品で成り立ちます。1つはメッセージを組み立てて送る「信頼できる環境」で、Cloud Functions for Firebaseか自社のアプリサーバーがこれにあたります。もう1つは、各プラットフォームの配信経路を通じてメッセージを受け取るクライアントアプリです。受信側のSDKはiOS・Android・Web（JavaScript）のほか、Flutter・Unity・C++向けにも用意されています。送信の認証情報は端末に置きません。必ずサーバー側から送る設計です。

| 部品           | 置く場所                   | 主な役割             |
| ------------ | ---------------------- | ---------------- |
| 送信側（信頼できる環境） | 自社サーバー・Cloud Functions | 宛先の保存・本文の組み立て・送信 |
| FCMのバックエンド   | Google側                | 受付・保管・各OSの経路への中継 |
| 受信側（クライアント）  | Android・Apple・Webのアプリ  | 宛先IDの取得・通知の表示    |

Androidで受信するための条件も公式ドキュメントに明記されています。[AndroidでFCMを始めるガイド](https://firebase.google.com/docs/cloud-messaging/android/get-started)によれば、FCMのクライアントにはAndroid 7.0以上で、Google Playストアのアプリが入った端末（またはGoogle APIs付きのAndroid 7.0エミュレーター）が必要です。配布経路はPlayストアに限られませんが、Playストアの入っていない端末にはFCMで届けられません。法人向けの専用端末に配る場合は、この条件を最初に確かめてください。

FCMの前身は、Google Cloud Messaging（GCM）です。GCMは2019年にサーバーとクライアントのAPIが削除され、旧ドキュメントのURLは現在FCMの概要ページへ転送されます。「GCM」と書かれた古い解説記事や、サーバーキーで認証する旧HTTP APIのサンプルは、そのままでは動きません。2026年に新しく実装するなら、後述のHTTP v1 APIかAdmin SDKを前提にしてください。

## FCMでできること：宛先の3つの指定方法と料金がかかる範囲

FCMの役割は、アプリを開いていない端末へサーバーから知らせを届けることです。公式ドキュメントが挙げる用途は2つあります。新着メールのように「同期すべきデータがある」とアプリに知らせる用途と、通知を表示して利用者を呼び戻す用途です。チャットのように本文ごと送る場合でも、1通あたりのペイロードは4096バイトが上限です。トピック宛てのメッセージは2048バイトまでに制限されます。

| 宛先                | 向いている用途       | 主な制限                        |
| ----------------- | ------------- | --------------------------- |
| 単一の端末（FID／登録トークン） | 個人宛て通知・チャット   | Androidの1端末に毎分240件・毎時5,000件 |
| トピック              | 天気・ニュースなど公開情報 | 1端末の購読は2,000トピックまで          |
| 条件式（トピックの組み合わせ）   | 「A購読かつB購読」の配信 | トピックと同じ制限                   |

トピック配信は速さより処理量を優先した仕組みです。公式ドキュメントも、1台や少人数へ素早く安全に届けたいならトピックではなく端末指定を使うよう勧めています。複数の端末をまとめて扱う「デバイスグループ」は2027年9月29日に停止するため、新規の実装では使いません。利用者IDと宛先の対応表は自社のデータベースで持ちます。

料金は、Firebaseの料金表でCloud Messaging（FCM）が「No-cost」と明記されています。実際に費用が出るのは、送信処理を動かすCloud Functionsや、宛先を保存するFirestoreの読み書きです。Blazeプランの従量単価は[Firebaseの料金と無料枠の実額](/tech/details/16672/)にまとめています。

## プッシュ通知が届くまでの仕組み：送信から端末表示までの5段階の配信経路

FCMの配信には、送信側・FCMのバックエンド・各OSの配信経路・端末上のSDKの4者が関わります。

1. アプリが起動するとFCM SDKが端末を登録し、宛先となるID（FIDまたは登録トークン）を受け取る。アプリはこれを自社サーバーに保存する。
2. 自社サーバーやCloud Functionsが、宛先と本文を指定してHTTP v1 APIに送信する。
3. FCMのバックエンドがメッセージを受け付け、メッセージIDを返す。端末がオフラインなら保管する。
4. Android端末へはFCMがGoogle Play開発者サービス経由で、iOSへはAPNs、WebへはブラウザのWeb Pushサービス経由で届ける。
5. 端末上のSDKが受け取り、通知を表示するか、アプリのコールバックに渡す。

手順3でメッセージIDが返っても、端末に届いたとは限りません。公式ドキュメントも、IDは「配信のために受け付けた」ことを意味すると書いています。端末がDozeで眠っていれば通常優先度のメッセージは保管され、端末が一度もつながらなければ、既定では4週間で破棄されます。

### FCMトークンとFIDの違い：2026年に始まった宛先IDの移行手順

「FCMトークン（登録トークン）」は、FCMがアプリのインストール1件ごとに発行してきた宛先IDです。2026年からは、Firebase Installationsサービスが管理するFIDを宛先に使う方式が加わりました。Android版のCloud Messaging 25.1.0（2026年6月16日のリリースノート）でFIDによる登録が追加され、`getToken`・`deleteToken`・`onNewToken` が非推奨になっています。iOSは12.18.0（2026年8月19日）で `FCMToken` などのトークン系APIが非推奨になりました。Flutterのfirebase\_messagingも17.0.0（2026年10月15日）でFID登録のAPIを追加しています。

サーバー側でFIDを宛先に指定できる版は、Admin SDKの言語ごとに異なります。各リポジトリのリリースノートでは、Node.js 14.1.0（6月24日）、Python 7.5.0・Java 9.10.0（7月2日）、Go 4.21.0・.NET 3.6.0（7月8日）で「`fid` を有効化し `token` を非推奨にする」変更が入りました。HTTP v1 APIのリファレンスでも `token` は非推奨と表示され、「移行期間中はこのフィールドでもFIDを受け付ける」と注記されています。

クライアント側の手順は公式の[FCM登録管理のベストプラクティス](https://firebase.google.com/docs/cloud-messaging/manage-tokens)にあります。Androidでは、マニフェストにメタデータ `firebase_messaging_installation_id_enabled` を追加するとFIDでの登録が有効になり、FIDは `FirebaseMessagingService` の `onRegistered()` で受け取れます。このコールバックは起動時の定期同期に加え、FIDが変わったときにも呼ばれます。受け取るたびにサーバーへ送り、保存時刻も記録してください。同じページは、トークンを「近く非推奨になりFIDに置き換わる」と書いていますが、停止日はまだ示していません。

## 通知メッセージとデータメッセージの違い：処理の主体と用途別の使い分け

FCMのメッセージは、中身のキーで2種類に分かれます。`notification` を含むものが通知メッセージ、`data` だけのものがデータメッセージです。両方を1通に入れることもできます。

| 項目           | 通知メッセージ                 | データメッセージ             |
| ------------ | ----------------------- | -------------------- |
| 表示する主体       | OS（バックグラウンド時）           | アプリのコード              |
| Androidの受信処理 | 前面時のみ onMessageReceived | 常に onMessageReceived |
| 折りたたみ        | 常に折りたたみ可能               | 既定では折りたたまない          |
| 向いている用途      | お知らせ・キャンペーン             | 同期指示・チャット本文          |

表示内容をアプリ側で組み立てたい場合や、既読状態などで表示するかどうかを変えたい場合は、データメッセージにします。Androidで `onMessageReceived` に与えられる処理時間は数秒です。画像の取得など重い処理は、[WorkManagerの仕組みと採用判断](/tech/details/16038/)で扱うジョブに切り出すよう公式ドキュメントが指示しています。

### 優先度とTTL（有効期限）の設定：用途別の遅延と保管期間の目安

Androidの優先度は `normal`（既定）と `high` の2段階です。normalは端末が起きていればすぐ届きますが、Dozeモード中は解除されるまで遅れることがあります。highは眠っている端末を起こして届ける設定です。ただし、利用者に見える通知を出さない高優先度メッセージが続くと、FCMは直近7日間の挙動をアプリのインストール単位で評価し、通常優先度への降格やGoogle Play開発者サービスによる通知の代理表示を行うことがあります。降格したかどうかは、受信側で `getPriority()` と `getOriginalPriority()` を比べれば分かります。Dozeで止まる処理の範囲は[AndroidのDozeモードの仕組みと解除方法](/tech/details/4402/)で解説しています。

TTL（Time to Live）は、端末に届けられないときにFCMがメッセージを保管する最長期間です。AndroidとWebでは0〜2,419,200秒（28日）で指定し、指定しなければ4週間です。iOSではAPNsの `apns-expiration` ヘッダーで指定します。着信通知のように遅れて届いても意味がないものは、短いTTLにします。TTLを0にすると保管されず、その場で届かなければ破棄されますが、折りたたみの流量制限を受けないので遅延は最も小さくなります。

「スコア更新」のように最新の1通だけ届けばよいメッセージには、Androidでは `collapse_key`、iOSでは `apns-collapse-id` を付けます。同じキーの未配信メッセージは、新しいもので置き換えられます。Androidの通知メッセージは常に折りたたみ可能で、指定したcollapse\_keyは無視されます。Androidで同時に保管できる異なる折りたたみキーは4種類までです。

## FCMでプッシュ通知を送る方法：コンソール・HTTP v1 API・Admin SDKの使い分け

送信手段は、Firebaseコンソールの通知作成画面（Notifications composer）、HTTP v1 API、Firebase Admin SDKの3つです。担当者が画面から送るならコンソール、業務システムの処理から自動で送るならAPIかAdmin SDKを使います。

### Firebaseコンソールから送る場合：APIにないセグメント配信と現地時刻の予約

公式のFCMトラブルシューティングとFAQには、通知作成画面とFCM本体でできることの比較表があります。コンソールにしかない機能と、APIにしかない機能がはっきり分かれています。

| 機能              | コンソール | API・Admin SDK |
| --------------- | ----- | ------------- |
| アプリ版・言語などのセグメント | 可     | 不可            |
| アナリティクスのオーディエンス | 可     | 不可            |
| 端末の現地時刻で配信      | 可     | 不可            |
| 通知のファネル分析       | 組み込み  | なし            |
| データメッセージ（4KB）   | 不可    | 可             |

送信・受信・表示・開封の件数を見るコンソールの［レポート］タブは、[メッセージ配信の把握に関するガイド](https://firebase.google.com/docs/cloud-messaging/understand-delivery)によればAPIで送ったメッセージも対象で、Googleアナリティクスの有効化が条件です。表の「ファネル分析」は、通知作成画面に組み込まれたコンバージョンまでの分析を指します。コンソールで送れるのは通知メッセージ（2KBまで）で、カスタムデータを添えることはできます。Googleアナリティクスを使ったA/Bテストにも対応しています。注意したいのは取り消しです。[コンソールからの送信ガイド](https://firebase.google.com/docs/cloud-messaging/send/firebase-console)によれば、予約したメッセージは配信が始まる前なら取り消せますが、ファンアウト（各端末への配信）が始まった後は、コンソールからもFirebaseサポートからも止められません。全員宛ての配信は、テスト端末で表示を確かめてから予約してください。セグメント配信や開封率の集計を管理画面ごと外部サービスに任せる選択肢は[OneSignalとは？プッシュ通知の料金と実装手順、FCM直接送信との使い分け](/tech/details/18353/)で比較しています。

### HTTP v1 APIで1台に送るリクエスト：curlで動かす送信例

HTTP v1 APIのエンドポイントは `https://fcm.googleapis.com/v1/projects/プロジェクトID/messages:send` です。認証には、サービスアカウントから取得した、スコープ `https://www.googleapis.com/auth/firebase.messaging` の OAuth 2.0 アクセストークンを使います。有効期限のないサーバーキーで認証する旧APIは2023年6月20日に非推奨となり、2024年7月22日から段階的に停止されました。

```
curl -X POST \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  https://fcm.googleapis.com/v1/projects/my-project/messages:send \
  -d '{
    "message": {
      "fid": "端末のFID",
      "notification": { "title": "注文を発送しました", "body": "お届け予定は明日です" },
      "android": { "priority": "high", "ttl": "3600s" },
      "apns": { "headers": { "apns-priority": "10" } }
    }
  }'
```

HTTP v1 APIは、1回のリクエストで複数の宛先に送る機能（旧APIのmulticast）を持ちません。宛先ごとにリクエストを送るか、次のAdmin SDKのまとめて送るメソッドを使います。FCM側で宛先の登録が有効かだけを確かめたいときは、同じAPIに `validate_only` を true にして送ると、実際には配信されません。APNsやブラウザ側で届くかどうかまでは分からない点に注意してください。

### Admin SDKによる複数台への送信：失効した宛先を自動で削除する実装例

まとめて送る旧メソッド `sendAll()` と `sendMulticast()` は、Node.js版のfirebase-admin 13.0.0（2024年11月12日）で削除されました。さらに14.0.0（2026年6月8日）では `admin.messaging()` のような名前空間形式のAPIが削除され、`firebase-admin/messaging` から `getMessaging()` を読み込む形だけになりました。代わりに `sendEach()` と `sendEachForMulticast()` を使います。

以下は、Node.js 22以降と、2026年10月23日時点の最新版であるfirebase-admin 14.5.0（9月23日公開）で動かすサーバー側の実装例です。`loadFidsForUser`・`deleteFids` は、自社の認証とデータベースの処理に置き換えてください。

```
import { initializeApp, applicationDefault } from 'firebase-admin/app';
import { getMessaging } from 'firebase-admin/messaging';

initializeApp({ credential: applicationDefault() });

// 失効を示すエラーコード
const STALE = new Set([
  'messaging/registration-token-not-registered',
  'messaging/installation-id-not-registered',
]);

export async function notifyRestock(userId) {
  // DB から取り出した宛先（1回の呼び出しで最大500件）
  const fids = await loadFidsForUser(userId);
  // 宛先0件で呼ぶと invalid-argument の例外になる
  if (fids.length === 0) return;

  const res = await getMessaging().sendEachForMulticast({
    fids,
    notification: { title: '再入荷のお知らせ', body: 'お気に入りの商品が再入荷しました' },
    // Admin SDK の ttl はミリ秒
    android: { priority: 'high', ttl: 60 * 60 * 1000 },
    apns: { headers: { 'apns-priority': '10' } },
  });

  // 失効した宛先を拾って DB から消す
  const stale = res.responses
    .map((r, i) => (!r.success && STALE.has(r.error?.code) ? fids[i] : null))
    .filter(Boolean);
  await deleteFids(stale);
}
```

501件以上を渡すと、送信前に `messaging/invalid-argument` で例外になります。500件を超える場合は分割して呼び出してください。宛先ごとの失敗は例外にならず、`responses` の各要素に入ります。この例が扱うのは失効した宛先の削除だけです。14.5.0の型定義の説明では、メソッドが例外を投げた場合と、全件が失敗した結果が返った場合を「送信全体の失敗」としています。一時的なエラー（`messaging/server-unavailable`・`messaging/internal-error`）で失敗した宛先は、削除せずに時間をおいて再送する処理を別に用意します。旧方式で登録したアプリに送る場合は、`fids` の代わりに `tokens` を使います（型定義では非推奨扱い）。Admin SDKの初期化と認証情報の渡し方は[Firebase Admin SDKの導入と初期化](/tech/details/3451/)、送信処理をサーバーレスで動かす構成は[Cloud Functions for Firebaseのトリガー設計](/tech/details/16683/)を参照してください。

## 2027年9月29日に止まるFCMの旧サーバーAPI：Instance IDとデバイスグループの移行先

2026年9月、FCMはInstance IDのサーバーAPI一式とデバイスグループ機能を非推奨にしました。公式の[FCMトラブルシューティングとFAQ](https://firebase.google.com/docs/cloud-messaging/troubleshooting)によると、停止日は2027年9月29日です。それまで性能が落とされることはありませんが、停止後は呼び出しがエラーになります。2027年1月1日以降は、新しい利用者がこれらのAPIを使い始めることもできません。デバイスグループはさらに早く、[デバイスグループのガイド](https://firebase.google.com/docs/cloud-messaging/device-group)で2026年12月1日以降は新規プロジェクトが使い始められないとされています。サーバーキー方式の旧API停止（2024年）とは別の告知で、HTTP v1 APIへ移行済みのシステムでも対象になりえます。

| 停止するAPI                     | 主な用途                  | 移行先                       |
| --------------------------- | --------------------- | ------------------------- |
| iid/info                    | トークンの有効確認・購読の取得       | validate\_only送信・新トピックAPI |
| iid/v1:batchAdd・batchRemove | サーバーからのトピック購読         | FCM v1のトピック購読API          |
| iid/v1:batchImport          | APNsトークンからの一括登録       | 代替なし（APNs直送かiOS SDK）      |
| デバイスグループの管理                 | グループへの端末追加・削除         | 端末ごとの宛先へ送る                |
| デバイスグループ宛ての送信               | notification\_keyでの送信 | 端末ごとの宛先へ送る                |

影響が見落とされやすいのは、`iid/v1:batchImport` です。サーバー側でAPNsトークンをFCMの登録に変換する機能で、代わりのAPIは用意されません。iOSアプリにFirebase SDKを入れずにFCMで送っていた構成は、APNsへ直接送るか、アプリにFCMのiOS SDKを組み込むかを選び直す必要があります。デバイスグループ宛ての送信は、`messages:send` 自体は動き続けますが、2027年9月29日以降はグループのキーを宛先に受け付けなくなります。グループに属する端末のトークンは、停止日までならエクスポート用のAPIで取り出せます。停止後はグループのデータが保持されないため、取り出して自社のデータベースに移し、端末ごとに送る形へ切り替えます。

### Admin SDKでトピック購読している場合の言語別の必要版

Admin SDKの `subscribeToTopic()` は、内部で旧Instance IDのAPIを呼んでいました。同じFAQは、次の版より古いAdmin SDKでトピック購読を管理していると影響を受けると明記しています。メソッド名は同じままで、Admin SDKを上げれば呼び出し先が新しいAPIに切り替わります。ただしNode.js版を13系以前から上げる場合は、14.0.0の破壊的変更（名前空間形式のAPIの削除、Node.js 18・20の対応終了）も同時に受けるので、前の章の書き方へ直す作業が伴います。

| 言語      | 影響を受ける版  | 上げる先     |
| ------- | -------- | -------- |
| Node.js | 14.4.0以下 | 14.5.0以上 |
| Python  | 7.6.0以下  | 7.7.0以上  |
| Java    | 9.10.0以下 | 9.11.0以上 |
| Go      | 4.21.0以下 | 4.22.0以上 |
| .NET    | 3.6.0以下  | 3.7.0以上  |

Node.js版のfirebase-admin 14.5.0で、実際にどこへリクエストが飛ぶかを確かめました。Node.js 26.5.0上でnock 14を使い、送信方式をHTTP/1.1（`enableLegacyHttpTransport()`）に切り替えて通信を捕捉したうえで、ダミーの認証情報で `subscribeToTopic(['fidA', 'fidB'], 'news')` と `unsubscribeFromTopic()` を呼んだ結果が次のとおりです。

```
POST /v1/projects/demo-proj/registrations/fidA/topicSubscriptions?topic_name=news
POST /v1/projects/demo-proj/registrations/fidB/topicSubscriptions?topic_name=news
subscribe {"successCount":2,"failureCount":0,"errors":[]}
DELETE /v1/projects/demo-proj/registrations/fidA/topicSubscriptions/news?allow_missing=true
unsubscribe {"successCount":1,"failureCount":0,"errors":[]}
1001件: messaging/invalid-argument
```

送信先は `fcm.googleapis.com` の新しいトピック購読APIで、旧来の `iid.googleapis.com` には1件も飛んでいません。旧APIのように1回で複数の宛先をまとめて送るのではなく、宛先1件ごとに1リクエストを発行しています。1回の呼び出しで渡せる宛先が1,000件までという制限は変わらず、1,001件では送信前に例外になりました。旧APIを使い続ける `subscribeToTopicLegacy()` も残っていますが、型定義で非推奨とされています。

REST APIを直接呼んでいる場合は、[トピック購読の管理ガイド](https://firebase.google.com/docs/cloud-messaging/manage-topic-subscriptions)にある `projects.registrations.topicSubscriptions` へ書き換えます。登録IDにはFIDと登録トークンのどちらも渡せます。すでに購読済みの組み合わせを作ろうとすると、HTTP 409が返ります。FIDやトークンが変わると、古いIDの購読は新しいIDへ引き継がれません。購読中のトピックをサーバーかアプリで控えておき、新しいIDで購読し直す処理が要ります。

## Android・iOS・Webのクライアント設定：受信側で必要な準備

受信側の準備はプラットフォームごとに異なります。共通の作業は、Firebaseプロジェクトへのアプリ登録と、SDKの追加です。

- **Android**：Android 13（API 33）以降では、実行時権限 `POST_NOTIFICATIONS` を利用者に許可してもらわないと通知を表示できません。SDK（23.0.6以降）がマニフェストへの宣言は済ませていますが、許可を求めるダイアログはアプリが出します。
- **iOS**：APNs認証キー（.p8）をFirebaseコンソールのCloud Messagingタブに登録し、キーIDとチームIDを入力します。鍵の登録はサーバー側の準備で、アプリ側では起動時などに通知の許可を利用者に求め、`registerForRemoteNotifications` でAPNsへの登録を行います。スウィズリングを無効にする場合は、`Info.plist` に `FirebaseAppDelegateProxyEnabled` を追加して NO にし、APNsトークンの関連付けなどを手動で実装します。iOS版Firebase Unity SDKでは、スウィズリングを無効にしないよう公式ドキュメントが注意しています。証明書方式の更新やAPNsのエラーは[APNs証明書の取得・更新とエラー対処](/tech/details/5280/)にまとめています。
- **Web**：FirebaseコンソールでVAPID鍵を作り、公開鍵を `register(messaging, { vapidKey })` に渡します。FIDで登録する `register()` は、JavaScript SDK 12.14.0（2026年5月28日）で追加されました。Webの導入ガイドは、FIDのAPIと非推奨のトークンAPIを同じアプリで併用しないよう注意しています。バックグラウンドで受け取るには、既定ではサイトのルートに `firebase-messaging-sw.js` というService Workerを置きます。既存のService Workerを使う場合は、`register()` の `serviceWorkerRegistration` に登録済みのものを渡します。旧来の `getToken()` を使い続ける場合は、VAPID鍵を `getToken()` に渡します。Service Workerの登録や更新の流れは、[PWAとService Workerの実装手順](/tech/details/13214/)と共通です。

### 2026年10月のSDKメジャー更新で確認すること：最小対応版と配布方法

2026年10月7日の更新は、3つのプラットフォームすべてで破壊的変更を含みます。その後も小さな更新が続いており、10月23日時点の最新版は次のとおりです（Androidはリリースノートへの掲載前で、Mavenリポジトリの公開日）。

| 対象      | 最新版（公開日）                           | FCM利用者に関係する変更             |
| ------- | ---------------------------------- | ------------------------- |
| Android | BoM 35.1.0（10月21日）                 | FCM 26系でminSdk 24         |
| Apple   | SDK 13.1.1（10月22日）                 | iOS 15.0以上・CocoaPods配布の終了 |
| Web     | SDK 13.1.0（10月21日）                 | 13.1.0でMessagingの変更なし     |
| Flutter | firebase\_messaging 17.0.0（10月15日） | Apple SDK 13・BoM 35に追従    |

[Firebase Android SDKのリリースノート](https://firebase.google.com/support/release-notes/android)によると、BoM 35.0.0に対応するCloud Messaging 26.0.0と、Direct Boot対応版の26.0.0は、どちらも `minSdkVersion` をAPIレベル24（Android 7.0）に引き上げました。BoM 35.1.0が同梱するのは26.0.1です。アプリの `minSdk` が23以下のままだと、ビルドの段階で失敗します。`minSdk` 23（Android 6.0）を維持したいなら、BoMを34系に留めるか、FCMだけ25系の版を個別に指定します。25系も25.0.0でAPIレベル23以上が必須になっており、配布されている25.1.3のマニフェストも `minSdkVersion="23"` です。22以下を残すことは、25系でもできません。

[Firebase Apple SDKのリリースノート](https://firebase.google.com/support/release-notes/ios)では、13.0.0から最小対応版がiOS 15.0になり、新しい版はSwift Package Managerとバイナリでのみ配布されると告知されています。CocoaPodsで入れている既存プロジェクトは、Podfileのまま13系へは上がれません。Swiftパッケージは、Swift 6.2.3のコンパイラとXcode 26.2以降を求めます。13.1.0のCloud Messagingの変更は、APNsトークン設定時のメインスレッド処理の削減など不具合修正です。

React NativeやFlutterのラッパーを使っているアプリは、ラッパー側の対応版を待ちます。Flutterのfirebase\_messaging 17.0.0は、変更履歴でApple SDK 13.0.0への更新を破壊的変更とし、Android側もBoM 35とminSdk 24を必須にしました。React Native版の事情は[React Native Firebaseの導入と落とし穴](/tech/details/17052/)で整理しています。[Firebase JavaScript SDKのリリースノート](https://firebase.google.com/support/release-notes/js)を見ると、13.0.0の破壊的変更はAI Logicなど他の製品が中心です。それでもメジャー更新なので、同じバンドルに含めている製品の変更点も読んでから上げてください。

## FCMの送信上限と流量制限：クォータ超過を避ける送信側の設計

上限の多くは送信側の設計で避けられます。数値は公式の[FCMのスロットリングと割り当て](https://firebase.google.com/docs/cloud-messaging/throttling-and-quotas)などによるもので、変更される可能性があると明記されています。

| 項目                       | 上限                 |
| ------------------------ | ------------------ |
| プロジェクト全体の送信              | 毎分60万件（既定）         |
| 1端末への送信（Android）         | 毎分240件・毎時5,000件    |
| 折りたたみメッセージ               | 1端末20件まで、以降3分に1件   |
| 折りたたまないメッセージの保管（Android） | 1端末100件（上限到達で全件破棄） |
| トピックの購読・解除               | 毎秒3,000件（プロジェクト単位） |
| 同時に進むファンアウト              | 1,000件（プロジェクト単位）   |
| Admin SDKの一括送信           | 1回500件             |

毎分60万件のクォータは、リクエスト数ではなくメッセージ数で数えます。400番台のクライアントエラー（429を除く）もカウントの対象です。失効した宛先へ送り続けるとクォータを無駄にするので、前の章のコードのように失効した宛先を削除します。超過すると `429 RESOURCE_EXHAUSTED` が返るので、Retry-Afterがあればその待機時間を守り、なければ60秒待ってから指数バックオフで再送してください。増枠を申請できるのは、1日に5分以上連続してクォータの80%以上を使い、クライアントエラー率が5%未満の場合で、1回に増やせるのは最大25%です。大型セールのような一時的な増枠は、原則15日前までにFirebaseサポートへ依頼します。

## FCMの通知が届かないときの切り分け：8つの原因と確認の順番

「送信は成功したのに届かない」という問い合わせは、原因ごとに確認する場所が違います。全利用者で一斉に届かないなら、最初に[FCMのステータスダッシュボード](https://status.firebase.google.com/cloud-messaging/)で障害が出ていないかを見ます。特定の利用者だけなら、上から順に確認すると早く切り分けられます。

1. **宛先が失効していないか**：`UNREGISTERED`（HTTP 404）が返る宛先は、アンインストールなどで無効になっています。Androidでは270日使われなかった登録を、FCMが期限切れとして削除します。公式ドキュメントは、アプリ側で宛先を月1回更新し、サーバーでは保存時刻を記録して古い宛先を定期的に削除するよう勧めています。
2. **バックアップから復元した端末と競合していないか**：Firebase Installationsのデータは既定でバックアップ対象です。復元した端末と元の端末が同じFIDを持ち、FCMは1つのFIDに1つの登録しか持たないため、片方が登録すると他方が404になります。公式FAQは、`PersistedInstallation` で始まるファイルを自動バックアップから除外するよう勧めています。
3. **送信元の認証情報が合っているか**：`SENDER_ID_MISMATCH`（403）は、宛先に対応する送信者IDと送信要求の送信者IDが一致しない場合に返ります。iOSやWebだけ届かず `THIRD_PARTY_AUTH_ERROR`（401）が出る場合は、APNsの鍵かWeb Pushの鍵が無効です。
4. **通知権限が許可されているか**：Android 13以降で `POST_NOTIFICATIONS` が未許可だと、何も表示されません。通知権限をオフにしたアプリ宛ての高優先度メッセージは、降格の対象にもなります。
5. **アプリが前面にあるときの処理を書いているか**：通知メッセージは、アプリがバックグラウンドならOSが表示しますが、前面にあるときはアプリのコードで受けて表示しなければ何も出ません。公式FAQが「届かない」ときに最初に疑う原因として挙げています。
6. **省電力で遅れていないか**：normal優先度のメッセージは、Dozeが解除されるまで保管されます。すぐに届けたい通知はhighで送り、受け取ったら必ず通知を表示します。`onMessageReceived` の中でネットワーク通信を待つと処理が打ち切られることもあるので、通知を先に出し、追加の処理はWorkManagerに渡します。
7. **社内ネットワークでポートが閉じていないか**：FCMの受信には外向きの5228番ポート（ときに5229・5230番）を使います。社内Wi-Fiだけで届かないなら、ファイアウォールでこの3つのポートを開けているかを確かめます。FCMは固定のIPアドレスを公開していないため、GoogleのAS15169のIPアドレス帯を許可する必要があります。
8. **端末がFCMの受信条件を満たしているか**：Google Playストアの入っていないAndroid端末には届きません。現行のSDK（26系）を組み込んだアプリはAndroid 7.0未満の端末にインストールできず、25系はAndroid 6.0以上が対象です。特定の機種だけ届かないときは、まずこの条件を疑います。

端末に届いた割合を数字で見るなら、Android向けは「FCM Data API」の集計値、個々のメッセージを追うならBigQueryエクスポートを使います。BigQueryエクスポートとコンソールのレポートタブを使うには、Googleアナリティクスの有効化が必要です。

## FCMを採用する条件と見送る場面：FCM直接利用・配信サービス・APNs／Web Push直送の比較

プッシュ通知の実装方法は、FCMを直接使う形に限りません。FCMの上に管理画面を載せた配信サービスを使う形と、FCMを通さずに各OSの配信経路へ直接送る形があります。どれを選ぶかは、宛先を誰が管理するか、配信を誰が操作するか、どのプラットフォームに送るかで決まります。

| 方式          | 向いている条件          | 主な負担          |
| ----------- | ---------------- | ------------- |
| FCMを直接使う    | 自社サーバーで宛先を管理できる  | 宛先の保存・失効処理を自作 |
| 配信サービスを使う   | 担当者が管理画面で配信する    | サービスの月額料金     |
| 各OSの経路へ直接送る | 1つのプラットフォームだけに送る | OSごとの認証と送信処理  |

FCMを直接使うのが合うのは、Android・iOS・Webの2つ以上に同じ仕組みで送りたく、利用者IDと宛先の対応表を自社のデータベースで持てる場合です。送信件数による課金がなく、失効した宛先の削除は前述のAdmin SDKのコードで自動化できます。残る運用作業は、FIDの変更に合わせた宛先の更新、APNs鍵の管理、送信失敗の監視です。注文の発送や予約のリマインドのように、業務システムの処理から自動で送る通知はこの形が向いています。

配信サービスを選ぶのは、マーケティング担当者が開封率やA/Bテストの結果を見ながら、セグメントごとに配信を繰り返す場合です。FCMのコンソールでもセグメント配信とA/Bテストはできるので、Android・iOS向けのプッシュ通知だけなら、まずコンソールで足りるかを試します。メールなど他の経路とまとめて管理したい場合の選択肢と費用は、前述のOneSignalの記事で比べています。

FCMを見送ってよいのは、送り先が1つのプラットフォームに限られる場合です。iOSアプリだけなら、Appleの[APNsへの送信リクエスト仕様](https://developer.apple.com/documentation/usernotifications/sending-notification-requests-to-apns)に沿って自社サーバーから直接送れます。Webだけなら、標準の[Web Pushプロトコル（RFC 8030）](https://www.rfc-editor.org/rfc/rfc8030)とVAPID鍵で送る方法もあります。どちらも中継が1段減る一方、Androidへ広げるときに作り直しになります。将来Androidにも出す見込みがあるなら、最初からFCMで作れば、送信APIと宛先の管理をAndroid向けにも使い回せます。Google Playストアの入っていない端末が主な配信先なら、FCMは使えないので別の配信経路を選びます。

通知の設計は、宛先の保存先、ログイン状態との結び付け、2027年の停止に向けた移行計画まで含めると、アプリ本体の設計と切り離せません。プッシュ通知を含むアプリの要件整理から実装・運用までを相談したい場合は、一創の[スマホアプリ開発](https://www.issoh.co.jp/service/apps/native/)でお受けしています。

## よくある質問

### Firebase Cloud Messaging（FCM）とは何ですか？

Firebase Cloud Messagingの略で、Googleが提供するプッシュ通知の配信サービスです。自社サーバーからAndroid・iOS・Webアプリへ通知やデータを送れます。前身はGoogle Cloud Messaging（GCM）です。自動車の衝突被害軽減ブレーキも「FCM」と略されますが、別物です。

### FCMの料金はいくらですか？

FCM自体は無料で、Firebaseの料金表でも「No-cost」とされています。送信件数による課金もありません。費用がかかるのは、送信処理を動かすCloud Functionsやサーバー、宛先を保存するデータベースの利用分です。

### FCMトークンとは何ですか？

FCMがアプリのインストール1件ごとに発行してきた宛先IDで、「登録トークン」とも呼ばれます。2026年からはFirebase Installation ID（FID）を宛先にする方式へ移行中で、Android・iOSの新しいSDKではトークン系APIが非推奨になりました。公式ドキュメントはトークンが近く非推奨になると書いていますが、停止日は示しておらず、移行期間中はどちらの宛先でも送信できます。

### FCMのプッシュ通知はどういう仕組みで届きますか？

アプリが起動時にFCMへ登録して宛先IDを受け取り、自社サーバーに保存します。サーバーがその宛先を指定してHTTP v1 APIに送ると、FCMがAndroidへはGoogle Play開発者サービスの配信経路、iOSへはAPNs、Webへはブラウザのプッシュサービス経由で届けます。端末がオフラインの間の保管期間は、既定で最長4週間です。

### FCMの送信に上限はありますか？

あります。プロジェクト全体で既定は毎分60万件で、Androidの1端末には毎分240件・毎時5,000件までです。超えると429 RESOURCE\_EXHAUSTEDが返るので、Retry-Afterに従って再送します。ペイロードは1通4096バイト（トピック宛ては2048バイト）、Admin SDKの一括送信は1回500件までです。

## 関連記事

- [Firebase Admin SDKとは？導入・初期化からユーザー管理まで使い方を解説](/tech/details/3451/)
- [Firebaseの料金｜無料枠とBlaze超過単価の実額【2026年8月時点】](/tech/details/16672/)
- [APNs証明書とは｜取得・更新手順とAPNs-410/403エラーの原因別対処](/tech/details/5280/)
- [AndroidのDozeモードとは？Deep/Lightの違いと通知が遅れるときの解除方法](/tech/details/4402/)
- [OneSignalとは？プッシュ通知の料金と実装手順、FCM直接送信との使い分け](/tech/details/18353/)

---

出典: [FCM（Firebase Cloud Messaging）とは｜プッシュ通知の仕組み・送信方法とFID移行【2026年10月時点】](<https://www.issoh.co.jp/tech/details/3448/>)（株式会社一創）
