web-dev-qa-db-fra.com

Firebase Android onAuthStateChanged appelé deux fois

J'ai commencé à travailler avec le nouveau SDK Firebase.

Lorsque je suis en train de me connecter, je suis une méthode onAuthStateChanged appelée deux fois avec le même état (etc., connexion de l'utilisateur).

Je suis certain d’ajouter AuthStateListener à la référence FirebaseAuth.

De l'aide?

26
Adi

Oui, et c'est très énervant. Ceci est dû à un appel d'enregistrement. De plus, onAuthStateChanged sera appelé plusieurs fois dans de nombreux états, sans possibilité de savoir de quel état il s'agit.

Documentation dit:

onAuthStateChanged (Authentification FirebaseAuth)

Cette méthode est appelée dans le thread d'interface utilisateur en cas de modification de l'état d'authentification:

  • Juste après que l'auditeur ait été enregistré

  • Lorsqu'un utilisateur est connecté

  • Lorsque l'utilisateur actuel est déconnecté
  • Lorsque l'utilisateur actuel change
  • Quand il y a un changement dans le jeton de l'utilisateur actuel 

Voici quelques conseils pour découvrir l’état actuel:

  • Appel d'enregistrement: ignore le premier appel avec un drapeau.
  • Utilisateur connecté: le paramètre user from est! = Null.
  • Utilisateur déconnecté: l'utilisateur du paramètre est == null.
  • Changements d'utilisateur actuels: l'utilisateur du paramètre est! = Null et le dernier ID utilisateur est! = L'utilisateur id du paramètre 
  • Actualisation du jeton utilisateur: l'utilisateur du paramètre est! = Null et le dernier ID utilisateur est == l'ID utilisateur du paramètre

Cet auditeur est un désordre et très bugone. L’équipe de Firebase devrait se pencher sur la question.

32
Fabricio

Ma solution consiste à utiliser un booléen déclaré globalement pour signaler si onAuthStateChanged a déjà été appelé auparavant.

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;
                }
            }
        }
    };
5
YYY

Habituellement, je souhaite configurer l'interface utilisateur avant d'ajouter le programme d'écoute et répéter la configuration à tout moment lorsque l'état d'autorisation change (en évitant le double appel initial). Ma solution consiste à améliorer la solution d'indicateur booléen et à garder trace de l'ID utilisateur (et non du jeton) du dernier utilisateur, qui peut être null.

private FirebaseAuth firebaseAuth;
private String lastUid; // keeps track of login status and changes thereof

Dans onCreate , je récupère l'instance d'authentification et configure l'interface utilisateur en conséquence, avant d'ajouter l'écouteur dans onStart

@Override
protected void onCreate(Bundle savedInstanceState){
    ...
    firebaseAuth = FirebaseAuth.getInstance();
    getUserSetUI();
    ...
}

getUserSetUI définit lastUid selon l'instance d'authentification

private void getUserSetUI(){
    lastUid = (firebaseAuth == null || firebaseAuth.getCurrentUser() == null) ?
            null : firebaseAuth.getUid();
    setUI(!(lastUid == null));
}

L'écouteur vérifie si l'état a réellement changé

@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();
    }
}
0
Danielozzo