iOS において  
PWA 化した web ページにフォーカスがあるかないかで、  
service worker 上で動かす firestore の onSnapshot() が利いたり利かなかったりしています。

**(a) なぜ利かないのか？**  
**(b) どうやれば動かせるのか？**

ご存じの方、教えていただけませんか？

* * *

何をやっているのか、お話します。

下記 firestore のリアルタイム アップデートが service worker 上で利用可能かどうかを試しています。

> Cloud Firestore でリアルタイム アップデートを入手する  
>  <https://firebase.google.com/docs/firestore/query-data/listen?hl=ja>

service worker に用意したコード (db.js) は以下の通りです。

db.js

```

    const firebaseConfig = {...}
    
    const firebaseApp = firebase.initializeApp(firebaseConfig)
    const db = firebaseApp.firestore()
    
    const b1_ref = db.collection('bs').doc('b1') ........................ (1)
    const cs_ref = b1_ref.collection('cs') .............................. (2)
    
    cs_ref.onSnapshot((doc) => { ........................................ (3)
      b1_ref.update({
        updatedAt: new Date() ........................................... (4)
      })
    })
    
```

  * (1) collection `bs` とその document `b1` を用意
  * (2) collection `cs` を用意
  * (3) collection `cs` に変化があれば 
    * (4) document `b1` の field `updatedAt` が更新される

> firestore console の Panel view にて  
>  手動により直接 `cs` (2) を追加・削除すれば、  
>  service worker 上の `onSnapshot()` (3) が利いて  
>  `updatedAt` (4) が更新される

という段取りです。

これを service worker として持つ web ページを下記 2つの環境

  * PC 
    * windows 11 (version 22H2, OS Build 2261.1555)
    * google chrome (Version 112.0.5615.138)
  * mobile 
    * iPhone
    * iOS 16.4.1
    * safari → Add To Home Screen

で表示し、そのページに

  * フォーカス `あり` (ページが最前面にあり直接操作できる)
  * フォーカス `なし` (別のアプリが最前面にあるか、ページが最小化されていて、直接操作できない)

というの状況の違いで比較してみました。

その結果は以下の通りです。

| PC | iPhone  
---|---|---  
Focus **あり** | o | o  
Focus **なし** | o | x  
  
  * `o` ... onSnapshot() が利いて updatedAt が更新された
  * `x` ... onSnapshot() が利かず updatedAt が更新されなかった

* * *

以下は firestore の console で更新された際のハイライトのスクリーンショットです。

**フォーカスあり**  
(service workder の onSnapshot() が利いて service workder により `updatedAt`
が更新されてハイライト)  
[![onSnapshot\(\) が利いて updatedAt
が更新されてハイライト](https://i.stack.imgur.com/Vhap1.png)](https://i.stack.imgur.com/Vhap1.png)

**フォーカスなし**  
(onSnapshot() が利かず `updatedAt` の更新なし)  
[![onSnapshot\(\) が利かず updatedAt
の更新なし](https://i.stack.imgur.com/FSlSu.png)](https://i.stack.imgur.com/FSlSu.png)

* * *

**PC の場合、**  
ページを開いていれば、

  * フォーカスの有無にかかわらず onSnapshot() は利く
  * 最小化していても onSnapshot() は利く

**iPhone の場合** 、  
フォーカスが

  * ある場合は onSnapshot() が利く
  * ない場合は onSnapshot() が利かない

となりました。

iPhone 上でページにフォーカスがない場合、  
まるでページの service worker が眠っているかのように反応がありませんでした。

もしかしたら、  
iOS の仕様でフォーカスのないページの service worker は動作を一旦停止させられているんじゃないか、と言う感じです。

ページにフォーカスを戻すと、Queue に溜まっていた処理が一気に実行されたかのように更新されています。

以上のように、  
iOS 上で PWA 化した web ページを開いている際、

  * ページにフォーカスがあるかないかで onSnapshot() の挙動が変わるのはなぜか？
  * フォーカスがない場合でも onSnapshot() を利かせるにはどうしたら良いのか？

ということを知りたいです。

ご存じの方や関連情報をお持ちの方、お教えください。
CC BY-SA 4.0
2023-04-30T13:36:57.213
94692
2023-04-30T13:36:57.213
13813
question
firebase web-worker
iOS にて PWA 化したページの service worker で firestore の onSnapshot() を利かせたい