🔥

Firebase Auth の初期化を待って currentUser を確実に存在チェックする方法

2021/01/13に公開

はじめに

ログインしてるのに以下のオブジェクトが null で困ったことってありませんか?

firebase.auth().currentUser; // ログインしてても何故か null

今回はこの原因と対策について紹介したいと思います.

原因

これは Firebase Auth のログイン情報の初期化が, onAuthStateChanged 発火時に行われるのが原因です.
つまり onAuthStateChanged が発火する前に currentUser を参照してしまうとログインしていたとしても nullなってしまいます.

対策

パターン1

対策としては, 素直に onAuthStateChanged に登録する関数内user データを参照しましょう.

var unsubscribe = firebase.auth().onAuthStateChanged((user) => {
  if (user) {
    // ログインしていれば中通る
    console.log(user); // ユーザー情報が表示される
  }

  // 登録解除
  unsubscribe();
});

最後に unsubscribeonAuthStateChanged に登録していた関数を解除するのも忘れずに!

パターン2

非同期的な書き方はちょっと使いづらいって人はこんな感じで回避することもできます.

// Firebase Auth が初期化されたら
var initFirebaseAuth = () => {
  return new Promise((resolve) => {
    var unsubscribe = firebase.auth().onAuthStateChanged((user) => {
      // user オブジェクトを resolve
      resolve(user);

      // 登録解除
      unsubscribe();
    });
  });
};

// 使う側
window.onload = async () => {
  // 同期的に書ける
  var user = await initFirebaseAuth();

  // ログインしていれば中通る
  if (user) {
    console.log(user); // ユーザー情報が表示される
  }

  // 以降であれば currentUser にアクセスしても OK
  if (firebase.auth().currentUser) {
    // TODO: ログインしている場合の処理

  }
};

こっちのパターンでは Promise オブジェクトを返すようにして, 取得できた user オブジェクトを resolve することで, 使う側で async/await を使うことが可能となります.

同期っぽく user データに参照できているのが分かると思います.

おわりに

以上 Firebase Auth のちょっとした Tips でした.

前にウチのメンバーから 「ログインしてるのにログインしてないことになってるんですがどうしてですか?」という質問を受けて教えた内容なんですが, 結構ここで躓いちゃってる人もいるんじゃないかなと思いこの記事を書かせていただきました.

少しでも参考になれば幸いです.

Reference

公式ドキュメントでもこの辺詳しく書いてくれてます.

https://firebase.google.com/docs/auth/web/manage-users

Discussion