カサいる?を使い始めて最初に気づくのは「毎朝アプリを開かなくていい」ということだと思う。設定した出発時刻の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(使用回数の平方根)で減衰させている。最初のフィードバックは大きく影響し、使い続けるほど調整幅が小さくなる。ある程度使って「自分の基準」が安定したら、大幅なずれが起きにくくなる設計だ。