Vue RouterとFirebase Authenticationで認証が必要なページを作っていたが、ログアウト後に任意のページに飛ばそうと思ってもうまく行かなかった。
いろいろ試したけど、イベントリスナーonAuthStateChangedを多重登録しないよう事前にUnsubscribeしたら大丈夫になった。
SSSS.GRIDMANを見ると原作の内容よりも小学生のときの同級生がグリッドマンの絵つき道具袋を使っていたのを思い出します。
全体的なやり方は下記ページといっしょ。
qiita.com
qiita.com
最終的なコードは下記。
router.jsから抜粋
// 詳しくは公式ドキュメント // https://firebase.google.com/docs/reference/js/firebase.auth.Auth#onAuthStateChanged let onAuthStateChangedUnsubscribe router.beforeEach((to, from, next) => { if (typeof onAuthStateChangedUnsubscribe === 'function') { onAuthStateChangedUnsubscribe() } if (!to.matched.some(record => record.meta.requiresAuth)) { next() } else { onAuthStateChangedUnsubscribe = firebase.auth().onAuthStateChanged(function (currentUser) { if (currentUser) { next() } else { next({ name: 'login' }) } }) } })
認証にfirebase.auth().onAuthStateChangedのコールバックを使うようになっているが、それがbeforeEachのタイミングではなく、Firebaseをログアウトした瞬間先に動いてしまい全部loginに飛んでしまって、飛ばしたいページには行かなかったもよう。
これに限らず、以前も書いたけどonなんちゃらのイベントリスナ登録系はなんども登録しないように、また何度も登録が必要な場合は以前のを消し、多重登録しないようにするのが大事だと改めて思う。
uyamazak.hatenablog.com
追記
上記参考ページにあるとおり、firebase.auth().currentUserがある場合の処理を追加したら、ムダも減るし、Unsubscribeしなくてもほとんど問題ないような気がしてきた。
let onAuthStateChangedUnsubscribe router.beforeEach((to, from, next) => { if (!to.matched.some(record => record.meta.requiresAuth)) { next() } else { if (firebase.auth().currentUser) { next() return } else { if (typeof onAuthStateChangedUnsubscribe === 'function') { onAuthStateChangedUnsubscribe() } onAuthStateChangedUnsubscribe = firebase.auth().onAuthStateChanged(function (currentUser) { if (currentUser) { next() } else { next({ name: 'login' }) } }) } } })
- 作者: 川口和也,喜多啓介,野田陽平,手島拓也,片山真也
- 出版社/メーカー: 技術評論社
- 発売日: 2018/09/22
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
改訂新版 Vue.jsとFirebaseで作るミニWebサービス (技術書典シリーズ(NextPublishing))
- 作者: 渡邊達明
- 出版社/メーカー: インプレスR&D
- 発売日: 2018/10/05
- メディア: Kindle版
- この商品を含むブログを見る