正直に告白すると、これはSPLIT TIMERを作っていたとき一番泣かされた問題です。「通知、届くときと届かないときあるな…」というのに気づいたのが夜11時ぐらいで、その日は結局解決しないまま寝ました。次の日改めて調べ直して分かったことを、備忘録がてらまとめておきます。
まずOSを疑った
スマホは基本、バッテリーを守るために裏で動いてるタブの処理をがんがん間引きます。こっちがどれだけ丁寧に通知を送るコードを書いても、OSが「まあ後でいいでしょ」と判断すれば普通に後回しにされる。
ここに関してはWeb側にできることはほぼありません。
正直「そういうものだと諦める」以外の選択肢がありませんでした。
次はブラウザの差を疑った
特にモバイルSafariが厄介で、WebからのPush通知対応が他よりだいぶ遅れて入った経緯があるらしく、「同じサイトなのに、iPhoneだと通知の挙動が違う」みたいな現象にちょくちょく出くわします。テストしてるときに「あれ、さっきAndroidでは鳴ったのに」と一人でぶつぶつ言いながら検証していたのを覚えています。
犯人はtagだった
あと地味に厄介だったのが、Notifications APIのtagという仕組み。同じtagの通知は「重複」扱いされて、古いのが新しいのに差し替わったり、そもそも出なかったりします。短時間に似た通知を連発すると起きる現象で、これに気づくまで「なんでたまに通知が消えるんだ…」と原因不明のバグとして半日ぐらい格闘していました。
原因が分かった瞬間の「そういうことか」感はちょっと快感でした。同時に「先にドキュメント読んどけよ自分」とも思いました。
結論:音に頼るしかない
通知ごとにIDを変えたりrequireInteractionを指定したりと、コード側でできる工夫は一通り入れました。それでも、最終的にはOSとブラウザの気分次第という部分がどうしても残ります。
100%は無理。
だからSPLIT TIMERでは、許可も不要で確実に鳴ってくれる「音」をメインの通知手段に据えて、画面通知はあくまでオマケ扱いにしました。この結論にたどり着くまでに丸2日溶かしたので、同じ沼にハマってる人がいたら「音に頼るのが正解です」とだけ伝えたいです。
| 原因 | やったこと |
|---|---|
| OS側のバックグラウンド間引き | 諦めて音をメイン手段に |
| モバイルSafariのPush対応の遅れ | ブラウザ差を前提に設計 |
tagによる重複抑制 |
通知ごとに識別子を分ける |
もっと詳しく仕様を追いたい人は、MDNのNotifications APIのページが一番まとまっています。
