横断/運用基盤 / 通知基盤
横断/運用基盤 / 通知基盤
本ページは 2 段構成。上段が biz/CS 向け(ユーザー提示可)、下段(
## 🔧 実装詳細以降)が dev 向け。biz/CS がユーザーへ提示・転用してよいのは上段のみ。
概要
fincs サービスのプッシュ通知配信・未読バッジ集計の基盤レイヤ。Web ブラウザ・iOS PWA・Android PWA 上で動作するプッシュ通知の購読管理・配信処理・未読カウント集計をまとめて担当する。
主な構成要素:
- プッシュ通知購読管理: ユーザーがブラウザ・PWA で通知購読を ON にするとデバイスのトークンを取得・登録
- 2 経路の通知配信: Web ブラウザ・Android 向けの主経路と、iOS 向けの互換層経路(別アプリ「PushQuay」経由)の併用
- 通知設定(4 軸): 講座 / トークルーム / DM / メンションの 4 軸でユーザーが個別に通知 ON/OFF を制御可能
- 未読バッジ集計: 内部キャッシュとサーバーレス処理で未読数を効率的に取得
- OS バッジ更新: Service Worker が通知受信時に OS のバッジ(アイコンバッジ)を更新
主な利用想定は、新規トーク投稿・記事公開・配信開始・運営告知などの即時通知、未読カウントの集計と表示、iOS PWA での通知運用など。各機能側の通知発火条件(どんなイベントで通知するか)は機能側 PSD(../talk/notification.md 等)を参照。
iOS は PWA 化が前提: iOS Safari ではブラウザ自体に通知機能の標準サポートがないため、ホーム画面追加で PWA として動作させた状態でのみ通知を受け取れる。PWA 化されていない iOS ユーザーには「PushQuay」という互換層アプリを経由して通知を届ける運用を提供。
通知トークンの定期再送: Web Push の通知トークンは内部仕様により 14 日間で無効化される仕様のため、ブラウザ側で 1 時間ごと + 画面表示時に再送して有効性を維持する仕組みを持つ。
通知許可拒否後の復帰について: ユーザーが一度ブラウザで通知許可を拒否すると、サービス側からは再度の許可ダイアログを出せない。ブラウザ設定から手動で許可に戻す必要があるため、CS 案内で手順を提示する運用となる。
通知本文の長さ制限: トーク投稿などで本文が長い場合、通知に表示される本文は内部的に約 2KB で切り詰められる。全文は通知タップ後の本文画面で確認する。
📝 レビュー観点:
- 目的: プッシュ通知の配信と受信、未読カウントの効率取得
- 誰が使うか: 全ユーザー(受講者・講師)
- どこで使うか: ブラウザ・iOS PWA・Android PWA
- 隣接機能との関係: トーク通知(
../talk/notification.md)、メール(./delivery-engine.md)、PWA(./pwa.md)- CS 問い合わせで頻発する論点: 「通知が来ない」「iOS で通知出せるか(PWA 化必須)」「14 日後に通知が止まる」「未読バッジが古い」
- [本機能特有] FCM 経路と PushQuay 経路は両方発火: ユーザーがどちらでトークン登録しているかに依存
- [本機能特有] FCM Web Push トークンは 14 日 TTL: FE が 1 時間ごと + visibilitychange で再送
- [本機能特有] iOS は PWA 化必須: Notification API は PWA でのみ利用可
- [本機能特有] Firestore キャッシュ 40MB: 24 時間で再初期化、3MiB 超 localStorage で削除
- [本機能特有] 未読集計は Firebase Cloud Functions: バックエンド負荷分散
利用シナリオ
シナリオ 1: 新規トーク投稿でプッシュ通知を受け取る
トークルームで他の受講者・講師が新規投稿すると、プッシュ通知が即座にデバイスへ届く。Web ブラウザ・Android PWA は主経路、iOS PWA は同経路または互換層(PushQuay)経由で受信。
シナリオ 2: 通知購読 ON / OFF を切り替える
ユーザーがブラウザの通知許可ダイアログで許可 / 拒否を選択することで、購読を切り替え。許可済みの状態でも、講座 / トークルーム / DM / メンションの 4 軸で個別に通知設定を ON / OFF できる。
シナリオ 3: iOS でホーム画面追加 → PWA 化 → 通知受信
iOS ユーザーがホーム画面追加で PWA 化することで通知機能が利用可能になる。PWA 化していないと iOS では通知が届かない仕様のため、CS で「iOS で通知が来ない」相談時はホーム画面追加を案内する。
シナリオ 4: 未読バッジの表示
未読のトーク・通知がある状態でアプリを閉じると、OS のホーム画面アイコンに未読数のバッジが表示される。ユーザーが未読を確認すると自動的にクリアされる。
よくある失敗ケース
- 通知許可拒否後の復帰不可: ブラウザ側で一度拒否すると、サービス側からは再許可ダイアログを出せない。ユーザー本人がブラウザ設定から手動許可へ戻す必要がある
- PWA 化していない iOS で通知が来ない: iOS Safari は標準で通知非対応。ホーム画面追加 + 互換層経由が必要
- トークン無効化による通知途絶: 14 日経過したまま画面を開かないと、トークンが無効化されて通知が途絶する。画面を開いてトークン再送が走れば復帰
- OS バッジが古い表示: 内部キャッシュの整合性問題で、実際の未読数とバッジ数値がずれるケース。整合性メンテナンス(
../admin/master.mdのセレクション既読再同期等)で対応
権限別仕様
権限定義は ../user-roles.md 参照。
通知基盤は基盤機能のため、ユーザー権限軸での直接の操作は無い。機能側の通知設定は ../talk/notification.md を参照。
| 操作 | 受講者 | 講師 | 運営アドミン |
|---|---|---|---|
| プッシュ通知購読 ON / OFF | ○ | ○ | ○ |
| 通知設定(講座 / トークルーム / DM / メンション) | ○ | ○ | ○ |
| 受信解除(プッシュ) | ○ | ○ | ○ |
機能詳細(ふるまい)
プッシュ通知の購読
- ユーザーが画面を開いた際にバックグラウンドで Service Worker が起動 + 通知トークン取得 → サーバーに登録
- 主経路(Web Push)と互換層経路(PushQuay)の両方を並行して登録する仕組み
- ユーザーがどちらの経路でトークン登録しているかに依存して、どの経路から通知が届くかが決まる
iOS の PushQuay 経路
- iOS Safari は PWA 化しないと通知機能を利用できない
- PWA 化していない iOS ユーザー向けに、別の互換層アプリ(PushQuay)経由で通知を受け取る経路を提供
- 互換層アプリ側でトークン登録 / 解除を行う運用
通知設定(4 軸)
ユーザーが 4 軸で個別に通知 ON/OFF を制御可能:
- 講座単位: 特定講座の通知をまとめて ON/OFF
- トークルーム単位: 講座内の特定ルームの通知のみ ON/OFF
- DM 通知: ダイレクトメッセージの通知 ON/OFF
- メンション通知: 自分が言及された投稿の通知 ON/OFF
これらの設定は通知配信の対象判定と、未読カウントへの反映に使われる。
未読バッジ集計
- 内部キャッシュ(ブラウザ側 IndexedDB)と、サーバーレス処理(クラウド関数)の組み合わせで未読数を効率的に取得
- BE への直接負荷を抑えつつ、リアルタイム性を確保する構成
- 大量のトークルーム・コンテンツに対する一括未読チェックを効率化
Service Worker と OS バッジ更新
- Service Worker が通知イベントを受信
- 受信時に通知を表示し、内部の未読カウントを更新
- OS のホーム画面アイコンバッジ(数字バッジ)を更新
通知配信の本文長制限
- 通知本文の長さは内部仕様により約 2KB で切り詰め
- 通知タップ後の本文画面では全文を表示
📝 レビュー観点:
- 入力 → 処理 → 出力: 投稿・配信トリガー → BE が FCM/PushQuay へ送信 → デバイス受信 → SW が表示
- エッジケース: Notification permission denied から復帰、14 日 TTL でトークン無効化、トークン重複(複数端末同期)
- エラー表示: 通知失敗時はエラーログ + AWS ログ基盤に記録、
UNREGISTEREDトークンは自動削除- [本機能特有] 通知許可拒否後の復帰不可:
requestPermissionで再度許可を求めても denied が変わらない
admin 操作
該当なし / 実装されていない
- 手動配信の運営アドミン UI: 専用画面は無し
- 配信ログの運営閲覧 UI: 未実装(AWS ログ基盤側で確認)
📝 レビュー観点:
- 運営アドミン側からの介入経路の必要性
品質 / 約束事項
- 応答性: 投稿から数秒以内に通知配信
- 信頼性: 500 件単位 partition +
@Async並列送信、20 秒超で内部監視通知。UNREGISTEREDトークンは自動削除 - 制限値:
- トーク本文 truncate: 2048 byte(FCM 制限)
- 同時送信パーティション: 500 件
- Firestore キャッシュ: 40MB IndexedDB
- localStorage 閾値: 3MiB 超で
firestore_*キー削除 - トークン TTL: FCM Web Push 14 日(FE 側で 1 時間ごと再送)
- データ保持: トークン・通知設定は内部的に保持、配信ログは AWS ログ基盤
📝 レビュー観点:
- [本機能特有] iOS の Web Push 16.4+ 対応の最新検証状況
変更履歴(リリースノート候補)
v2.29.2: 2026-05-04(PSD 初版)
- [PSD 追加] 本ドキュメント初版作成。v2.29.2 時点の実装を起こし。機能追加・変更は含まない
📝 レビュー観点:
- 過去の主要変更(PushQuay 互換層導入 / Firestore キャッシュ導入 / Cloud Functions 経路導入 等)
関連ドキュメント
- 権限定義:
../user-roles.md - 用語辞書:
../terminology.md - 関連 PSD:
../talk/notification.md— トーク通知./pwa.md— PWA / Service Worker./delivery-engine.md— メール配信エンジン