新しいFirebase SDKの使用を開始しました。
ユーザーログインを実行しているときに、onAuthStateChangedメソッドが同じ状態で2回呼び出されています(ユーザーのサインインなど)。
AuthStateListenerをFirebaseAuth参照に1回だけ追加すると確信しています。
何か助けは?
はい、これは非常に迷惑です。これは登録呼び出しによるものです。それだけでなく、onAuthStateChangedは多くの異なる状態で何度も呼び出され、どの状態であるかを知ることはできません。
Documentation は言う:
onAuthStateChanged(FirebaseAuth auth)
このメソッドは、認証状態の変化時にUIスレッドで呼び出されます。
リスナーが登録された直後
ユーザーがログインしているとき
- 現在のユーザーがログアウトしているとき
- 現在のユーザーが変更されたとき
- 現在のユーザーのトークンに変更がある場合
ここでは、現在の状態を発見するためのいくつかのヒントを示します。
このリスナーは混乱し、非常にバグが発生しやすくなります。 Firebaseチームが調査する必要があります。
私の回避策は、グローバルに宣言されたブール値を使用して、onAuthStateChangedを前に呼び出す必要があるかどうかにフラグを付けることです。
private Boolean authFlag = false;
mAuthListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull final FirebaseAuth firebaseAuth) {
if (firebaseAuth.getCurrentUser() != null) {
if(authFlag== false) {
// Task to perform once
authFlag=true;
}
}
}
};
ここで提供されている他の答えはうまくいくかもしれませんが、フラグを管理するのは面倒で間違いがちです。
私はイベントを短時間でデバウンスすることを好みます。たとえば、ユーザーが200ミリ秒以内にログインしてからログアウトすることはほとんどありません。
[〜#〜] tldr [〜#〜]
Debouncingは、イベントを処理する前に、事前定義された期間内に同じイベントが再び発生するかどうかを確認するために待機することを意味します。もしそうなら、あなたはタイマーをリセットし、再び待ちます。そうでない場合は、イベントを処理します。
これはAndroid質問です。これは私の分野ではありませんが、きっとAndroidは、タスクに役立つ何らかの種類のツールを提供します。 、簡単なタイマーで作ることができます。
JavaScriptの実装は次のようになります。
var debounceTimeout;
const DebounceDueTime = 200; // 200ms
function onAuthStateChanged(auth)
{
if (debounceTimeout)
clearTimeout(debounceTimeout);
debounceTimeout = timeout(() =>
{
debounceTimeout = null;
handleAuthStateChanged(auth);
}, DebounceDueTime);
}
function handleAuthStateChanged(auth)
{
// ... process event
}
通常、私はリスナーを追加する前にUIをセットアップし、いつでもセットアップを繰り返します認証状態が変化します(最初の二重呼び出しを回避します)。私の解決策は、ブールフラグソリューションを拡張し、最後のユーザーのuid(トークンではない)を追跡することです。これはnullの場合があります。
private FirebaseAuth firebaseAuth;
private String lastUid; // keeps track of login status and changes thereof
onCreateでは、リスナーをonStartに追加する前に、認証インスタンスを取得し、それに応じてUIを設定します
@Override
protected void onCreate(Bundle savedInstanceState){
...
firebaseAuth = FirebaseAuth.getInstance();
getUserSetUI();
...
}
ここで、getUserSetUIは、認証インスタンスに従ってlastUidを設定します
private void getUserSetUI(){
lastUid = (firebaseAuth == null || firebaseAuth.getCurrentUser() == null) ?
null : firebaseAuth.getUid();
setUI(!(lastUid == null));
}
リスナーは、状態が実際に変更されたかどうかを確認します
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth auth){
String uid = auth.getUid(); // could be null
if( (uid == null && lastUid != null) || // loggedout
(uid != null && lastUid == null) || // loggedin
(uid != null && lastUid != null && // switched accounts (unlikely)
!uid.equals(lastUid))){
getUserSetUI();
}
}
if (authStateListener == null) {
authStateListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
if (firebaseAuth.getCurrentUser() == null) {
//Do anything here which needs to be done after signout is complete
FirebaseAuth.getInstance().removeAuthStateListener(this);
Log.d(TAG_, "logout");
finish();
} else {
}
}
};
}
FirebaseAuth.getInstance()。removeAuthStateListener(this)を呼び出す必要があります