Firebase Authで現在の認証状態を継続的に取得する方法がいくつかあるけど、
それぞれの違いを整理してみたときの備忘録(*´ω`*)
Admin SDKやFirebaseコンソールを使うと反映されないは罠。。
xxxChanges()の違い
3種類あるが、それぞれ呼び出されるタイミングはこんな感じ。
authStateChanges()
- リスナーの登録直後
- ユーザーがログインしたとき
- 現在のユーザーがログアウトしたとき
idTokenChanges()
authStateChanges()
のに加え、- 現在のユーザーのトークンが変更されたとき
userChanges()
idTokenChanges()
のに加え、FirebaseAuth.instance.currentUser
のメソッド呼び出し時reload()
/unlink()
updateEmail()
/updatePassword()
updatePhoneNumber()
/updateProfile()
authStateChanges()
が一番狭く、
userChanges()
が一番広い
Admin SDKで更新時の注意点
ドキュメントを見てみると、以下の注意点が書かれている。
idTokenChanges()
Firebase Admin SDK を使用してカスタム クレームを設定すると、このイベントは次の場合にのみ発生します。
userChanges()
Firebase Admin SDK で User プロファイルを更新しても、idTokenChanges()、userChanges()、authStateChanges() は呼び出されません。
Firebase Admin SDK や Firebase コンソールで User を無効にしたり削除しても、idTokenChanges()、userChanges()、authStateChanges() は呼び出されません。
なので、Admin SDKやFirebaseコンソールを利用して変更した場合、
変更後の情報は即座にクライアント側に反映されない。
無効化や削除しても一定期間ログイン状態のままになってしまう。。
更新されるタイミングとしては、以下の通り。
- ログインや再認証したとき
- 古いトークンが期限切れになったとき
currentUser.reload()
で再取得したときcurrentUser.getIdTokenResult(true)
でIDトークンを強制更新したとき
また、.reload()
やgetIdTokenResult(true)
を呼び出した際には、
user-disabled
やuser-not-found
などの例外が発生する可能性がある。
対処方法の案
なので、サーバ側でAdmin SDKを使っていたり、
Firebase コンソールからの変更を即座に反映したい場合、
クライアントで更新してやる必要がある。
案としては以下の3つ。万能なのはFirestoreの利用。
- 定期的に
.reload()
を呼び出す方法- クライアント側でx秒間隔で
.reload()
を呼び出す - 全プラットフォームで使えるが、リクエストが多い
- クライアント側でx秒間隔で
- Firestoreを使う
- サーバ側で更新してほしいときに特定のドキュメントを更新
- クライアント側で対象のドキュメントを
listen()
しておき、
変更があったらcurrentUser.reload()
を呼び出す - 全プラットフォームで使えるが、firestoreが必要
- Firebase Cloud Messagingを使う
また、FunctionsのAuthenticationトリガーも使えないか検討したけど、
作成/削除しか無いので、更新時などはハンドリングできない。。
以上!! 意外と罠があってびっくり。。(*´ω`*)