毎朝8時に通知が来る。「今日は傘いりません」——この通知が届くまでに何が起きているか、書いておきたいと思います。カサいる?の通知システムは、「確実に届く」ことを最優先に設計されています。リモートプッシュとローカル通知のデュアル構成により、どちらかが必ずユーザーに届くようになっています。

リモートプッシュ(FCM)

Firebase Cloud Messagingを使ったプッシュ通知です。サーバー側ではSupabaseのPostgreSQLに組み込まれたpg_cronが、毎日指定時刻にEdge Functionを起動します。Edge FunctionはアクティブなユーザーのFCMトークンを取得し、各ユーザーの傘判定を計算して通知を送信します。

ローカル通知(フォールバック)

FCMトークンが未登録の場合やネットワークが不安定な場合は、flutter_local_notificationsによるローカル通知がフォールバックとして機能します。タイムゾーンはAsia/Tokyoを基準にスケジュールされます。

マルチデバイス対応

FCMトークンはuser_notification_tokensテーブルにデバイス単位で格納されます。スマホとタブレットの両方で同じアカウントを使えば、それぞれに通知が届きます。無効になったトークンは自動的にクリーンアップされます。

ユーザー別タイミング

通知時刻はユーザーごとにカスタマイズ可能です。デフォルトは朝8:00・夕方18:00(JST)ですが、早朝出勤の方は6時、遅番の方は9時など、生活リズムに合わせられます。

匿名デバイス対応

アカウント登録なしでも、デバイスIDベースで通知を受け取れます。まずは気軽に試してみたいユーザーにも、フル機能の通知体験を提供します。

バッチ処理

Edge Functionは大量のユーザーへの通知をバッチ処理(BATCH_SIZE=50、同時実行数=10)で送信します。スケール性を確保しつつ、APIレートリミットを超えない制御が行われています。