🤖

【Go×FCM】定期的にFCMへPush通知を送信する機能を実装:サーバー編

2024/05/04に公開

はじめに

前回、こちらの記事で、Firebase Cloud Messaging(FCM)を利用して、iOS実機にバックグラウンド・フォアグラウドでのテスト送信を行うところまでを記載した。

https://kazulog.fun/dev/flutter-fcm-push-test-notification/

今回は、Go言語でサーバーから定期時刻にFCMにPush通知を送信する機能を実装したいと思う。

FCMにPush通知を実装するのに必要な引数は下記4つ

  • FCMサーバーキー:HTTPリクエストヘッダーのAuthorization
  • デバイスのFCMトークン:メッセージの送り先の指定として
  • タイトル
  • 本文

FCMサーバーキーの取得

FCMのサーバーキーをHTTPリクエストのヘッダーの Authorization として設定して、HTTPリクエストを介してFCMエンドポイントにメッセージを送信するので、まずFCMのサーバーキーを取得する必要がある。

ただ、Cloud Messaging API(Legacy HTTP API)は2024年6月20日をもって廃止され、FCMサーバーキーは使用できなくなるので注意。

Firebaseコンソール→プロジェクトの設定→Cloud Messagingタブ→Google CloudコンソールでAPIを管理をクリック。

すると、外部遷移するので、Cloud Messagingを「有効にする」をクリック

有効にした後に、「Cloud Messaging」タブに戻るとサーバーキーが表示されるので、コピーする。

FCMトークンをサーバーに送信

サーバーからFCMバックエンドにプッシュ通知を送る際には、個々のデバイスを識別するFCMトークンを引数として渡す必要がある。

サーバーで格納しているUserテーブルにFCMトークンというカラムを新規に追加して、ユーザーが初回アプリ起動したタイミングで、DBに保存されるようにして、実際に通知を送る際はDBのFCMトークンカラムから呼び出すという流れで実装する。

Go:データベースにFCMトークンを格納するためのカラムを追加

$ cd scripts/migrations
$ migrate create -ext sql -format 2006010215 add_fcm_token_to_users

upとdownのsqlファイルが作成されるので、下記のように記載。

// 2024050323_add_fcm_token_to_users.up.sql
ALTER TABLE users 
  ADD COLUMN fcm_token VARCHAR(255);
// 2024050323_add_fcm_token_to_users.down.sql
ALTER TABLE users 
  DROP COLUMN fcm_token;

migration適用して、fcm_tokenカラムをUserテーブルに追加した。

Go:**User構造体にfcm_token**フィールドを追加

Goの**User構造体にfcm_tokenフィールドを追加してfcm_token**フィールドをデータベースから読み書きできるようする。

// user.go
type User struct {
    UID                        string `db:"uid"`
    DeviceID                   string `db:"device_id"`
    Name                       string `db:"name"`
    // ... 他のフィールド
    FcmToken                   string `db:"fcm_token"` // この行を追加
}

Go:**UpdateUser関数を更新して、fcm_token**を扱えるようにする。

// user_db.go
func UpdateUser(db *sqlx.DB, user *User) (*User, error) {
	tx, err := db.Beginx()
	if err != nil {
		return nil, err
	}

	query := `update users
			  set device_id				    = coalesce(:device_id, device_id),
			  ...
			  fcm_token = COALESCE(:fcm_token, fcm_token),
			  ...
			  WHERE uid = :uid;`
	return &updatedUser, nil
}

Flutter:アプリ起動時にFCMトークンをサーバーに送信

FCMトークンをユーザーデータの一部として取り扱い、ApiClient クラスを使用して API リクエストで管理する。

Dartの**User**モデルがFCMトークンのフィールドを含むようにし、このモデルを更新して、このフィールドのシリアライズとデシリアライズが行えるようにする。

// lib/api/user.dart
class User {
  final String? uid;
  final String? fcmToken; // この行を追加

	User(
      {this.uid,
			 this.fcmToken});
}

**build_runner**を使用して、JSONシリアライズのコードを生成する

flutter pub run build_runner build --delete-conflicting-outputs

次に、アプリが起動した際に、FCMトークンを取得し、サーバーに送信する機能を**main.dartに実装する。UserNotifierupdateUserメソッドは既にUser**オブジェクトを受け取って更新する機能を持っているため、このメソッドを使ってユーザーのFCMトークンを更新する。

続きはこちらで記載しています。
https://kazulog.fun/dev/fcm-go-server-cron/

Discussion