5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PUSH通知を実際に送らなくてもFCMトークンが有効かを検証したい

Last updated at Posted at 2025-12-08

概要

Firebase Cloud Messaging(FCM)ではFCMトークンを利用してPUSH通知の送り先を指定します。

FCMトークンはユーザがアプリをアンインストールしたり、アプリを一定期間立ち上げなかったりすると失効し無効なトークンとして扱われます。そのため、失効したトークンを管理しておかないと、無駄な通知処理が発生し、パフォーマンスの低下やコスト増加を招く可能性があります。

実際に配信を行えば、トークンが失効しているかが判定できますが、PUSH通知を送らずにトークンの有効性を確認する方法が必要になる場合があります。以下がその例です

  • 元々有効なトークンの管理をしておらず、把握している全トークンの有効性を一括で確認したい
  • 一度無効と判断したトークンの有効性を再度チェックしたい(実際一度無効判定になったトークンが復活するケースを確認している)

この記事では、FCM APIのvalidate_onlyフラグを使って安全にトークンの有効性を検証する方法を紹介します。今回はPython(firebase-admin SDK)での実装事例を前提としています。

ポイント

1. validate_onlyフラグの活用

FCM APIのprojects.messages.sendにはvalidate_onlyというフラグがあります。これをtrueに設定することで、実際に配信せずにバリデーションだけを
実行できます。

Pythonのfirebase-admin SDKでは、dry_runパラメータがこのvalidate_onlyフラグに対応しています:

batch_response = messaging.send_each(messages, dry_run=True)
  • dry_run=True(= API の validate_only: true): バリデーションのみ実行、実際の配信は行われない
  • dry_run=False(= API の validate_only: false): 実際に配信される

dry_run=Trueが実際に機能しているかの見分け方

dry_run=True が実際に機能しているかどうかはレスポンスのmessage_idで判別できます。通常message_idはリクエストごとにユニークなIDが返されますが、dry_run=Trueの場合は常に以下のように固定のIDが返されます:

  • dry_run=Trueの場合: projects/{project_id}/messages/fake_message_id
  • dry_run=Falseの場合: projects/{project_id}/messages/{実際のメッセージID}

2. dataメッセージによる二重の安全策

万が一dry_runフラグが逆転してしまった場合(dry_run=Falseで実行されてしまった場合)でも、ユーザーへの誤配信を防ぐために、実際の配信では使用しないdataのみを設定したデータメッセージを利用します。FCMには通知メッセージとデータメッセージの2種類がありますが、ここではデータメッセージは受け取ったデータをクライアント側で処理する必要があり、無効な値だけの場合何も処理しないようになっていれば通知等は表示されません。

messages = [messaging.Message(
    token=token,
    data={
        'validation': 'true'  # 実際の配信で使用しないdataのみ
    }
)]

検証

上記の方法で実際に配信されるかどうかを検証しました。

検証結果

条件 message_id 配信
validationのdataのみ + dry_run=True fake_message_id 届かない ✅
validationのdataのみ + dry_run=False 正規のID 届かない(dataだけなので表示されない)✅
通常のdata + dry_run=True fake_message_id 届かない ✅
通常のdata + dry_run=False 正規のID 届く

実装例

以下が実際にユーザにPUSH通知を送らずにFCMトークンの有効性を確認するコードです。

#!/usr/bin/env python3
from firebase_admin import messaging, initialize_app, credentials

def validate_fcm_tokens(tokens, project_id, credential_path):
    """FCMトークンの有効性を検証する(実際の配信は行わない)"""

    cred = credentials.Certificate(credential_path)
    initialize_app(credential=cred, options={'projectId': project_id})

    # 安全のため、validationフラグのみをdataとして設定
    messages = [
        messaging.Message(
            token=token,
            data={'validation': 'true'}
        )
        for token in tokens
    ]

    # dry_run=Trueでバリデーションのみ実行(APIのvalidate_only=trueに相当)
    batch_response = messaging.send_each(messages, dry_run=True)

    valid_tokens = []
    invalid_tokens = []

    for idx, response in enumerate(batch_response.responses):
        if response.success:
            valid_tokens.append(tokens[idx])
        else:
            error_code = response.exception.code if response.exception else "Unknown"
            invalid_tokens.append((tokens[idx], error_code))

    return valid_tokens, invalid_tokens

まとめ

  1. FCM APIのvalidate_onlyフラグ(Python SDKではdry_run=True)を使えば、実際に配信せずにトークンの有効性を確認できる
  2. 万が一に備えて、実際の配信で使わないdataのみを設定することでより安全にトークンの有効性を確認できる

この方法を使えば、FCMトークンの有効性を安全に検証でき、無効なトークンを効率的に管理できます。

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?