Firebase timeout 問題

0x00 背景

firebase/firestoreの診断を行う時に、burpを使うと、下記のようなtimeoutエラーが出る。これの解決法をここにまとめる。

[2021-11-04T09:18:26.044Z]  @firebase/firestore: Firestore (7.6.2): Could not reach Cloud Firestore backend. Backend didn't respond within 10 seconds.
This typically indicates that your device does not have a healthy Internet connection at the moment. The client will operate in offline mode until it is able to successfully connect to the backend.

0x01 解決方法

breakpointをしかけて、forceLongPolling を trueにする。

具体的に、chromeのdevtoolでxxx.chunk.jsを開いて、 this.forceLongPolling を見つけ、この行(36472)にbreakpointを仕掛ける。この行の実行が終わったら、forceLongPollingの値をtrueにして実行を続ける。

Local Overrides を使う

上の図と同じく、xxx.chunk.jsで右クリックして、Save for overridesを選んで、Enable Local Overridesにチェックを入れる。

そしたらローカルにxxx.chunk.jsが保存され、このxxx.chunk.jsを編集して保存すればなんでもできる。ここでは36472行目を this.forceLongPolling = true に編集して保存し、ページをリロードすると、timeout エラーが出なくなる。

0x02 consoleでjsを使う場合

var fire_scripts = ["/7.9.1/firebase.js","/9.1.2/firebase-app.js","/9.1.2/firebase-firestore.js","/9.1.2/firebase-auth.js"]; // 最新版を指定する
for(var i=0; i<fire_scripts.length; ++i){
    var s = document.createElement("script");
    s.type = "module";
    s.src = "https://www.gstatic.com/firebasejs"+fire_scripts[i];
    document.getElementsByTagName("head")[0].appendChild(s);
}

var config = {
  apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxx",
  authDomain: "xxxxxx.firebaseapp.com",
  databaseURL: "https://xxxxxxxx.firebaseio.com",
  projectId: "xxxxxxxxxxxx",
  storageBucket: "xxxxxxxx.appspot.com",
  messagingSenderId: "111111111111"
};

var firestore;
setTimeout(function(){
  firebase.initializeApp(window.config);
  firebase.auth().setPersistence(firebase.auth.Auth.Persistence.SESSION).then(function() {
           firebase.auth().tenantId="xxxxxxxxxxxx";
           firebase.auth().signInWithEmailAndPassword("nevermoe@example.com", "yourpassword").catch(function(error) { //emailとpwログインの場合これ使う
      alert("login failed");
    });
  });
  firestore = firebase.firestore();
  const settings = {timestampsInSnapshots: true, experimentalForceLongPolling: true};
  firestore.settings(settings);
},5000);

上のコードをconsoleで実行できたら、下記のコードでログイン成功してるかを検証できる。

firebase.auth().currentUser.uid
docRef=firestore.doc("/collectionxxx/docxxx/subcollectionyyy/docyyy")
docRef.get().then((doc) => {
    if (doc.exists) {
        console.log("Document data:", doc.data());
    } else {
        // doc.data() will be undefined in this case
        console.log("No such document!");
    }
}).catch((error) => {
    console.log("Error getting document:", error);
});