カサいる?を使い始めて最初に気づくのは「毎朝アプリを開かなくていい」ということだと思う。設定した出発時刻の30分前になると「今日は折りたたみ傘を持って」という通知が届く。これだけで傘の判断が終わる。
ただ、その通知が届くまでの裏側を知ると、設計のこだわりが少し伝わると思う。
通知の直前に何が起きているか
毎朝の通知は、届く直前に天気データを取得して計算している。前の晩に計算しておく方法もあったが、それでは朝の天気予報の更新を反映できない。天気予報は深夜から早朝にかけて精度が上がることが多い。通知のギリギリに計算することで、その日の最新の予報を使える。
処理の流れはこうなっている。
1. 出発時刻の30分前: 30分ごとのcronがトリガーされ、サーバー側のスケジューラが起動
2. 自宅・職場の座標をもとに天気APIから降水確率を並列取得
3. 交通手段×降水確率×朝夕判定のリスクスコアを計算
4. 「不要/折りたたみ/大きい傘」の3段階に変換
5. FCM(Firebase Cloud Messaging)で端末に通知を送信
この一連の処理がユーザーの目に触れることなく走っている。
FCMとローカル通知の二重構造
通知が届かないことを減らすため、FCMによるサーバー起点の通知と、デバイス内のローカル通知を二重に走らせている。
FCMはサーバーから端末に通知を送るプッシュ通知の仕組みだ。ただしFCMはネットワーク状況によって遅延することがある。特に起床直後のスリープ明けでは、プッシュが数分遅れることもある。
そこでデバイス側でもローカル通知をスケジューリングしておく。FCMが届かない場合でも、デバイス内のタイマーが発火して傘判定を表示する。
「通知が届かなかったので今日の判定がわからなかった」という状況を避けたい——この一点のための二重構造だ。
傘判定と服装アドバイスが同時に届く理由
通知には傘判定だけでなく、アプリ内の判定ロジックが生成した服装アドバイスも含まれる。「今日は折りたたみ傘を持って。朝晩で気温が10℃下がるので薄手のアウターがあると安心です」のような形だ。
これは別々の通知を2回送るのではなく、1回の通知にまとめている。朝に通知が2回届くより、1回で全部わかる方が邪魔にならないという判断だ。
「傘が必要かどうか」と「今日何を着るか」は、出かける前に同時に解決したい問いだ。それを1回の通知で済ませることが、「朝の1分を0分にする」という目標に誠実だと思っている。
感度の調整について
判定が「自分の感覚とずれる」と感じたら、フィードバック機能で感度を調整できる。「今日の判定は不要だったけど実際は少し降った」と送ると、その通勤ルートのリスクスコアの閾値が少し低くなる。
フィードバックの重みは√n(使用回数の平方根)で減衰させている。最初のフィードバックは大きく影響し、使い続けるほど調整幅が小さくなる。ある程度使って「自分の基準」が安定したら、大幅なずれが起きにくくなる設計だ。