with studio sesion register puede password inicio iniciar con autenticacion and android firebase firebase-authentication

studio - Firebase Android onAuthStateChanged() se dispara dos veces después de iniciar sesión con correo electrónico y contraseña()



no se puede iniciar sesion con firebase (3)

La doble llamada se debe una llamada de registro. No solo eso, onAuthStateChanged se llamará muchas veces en muchos estados diferentes, sin posibilidad de saber qué estado es.

Documentation dice:

onAuthStateChanged (autenticación FirebaseAuth)

Este método se invoca en el subproceso de la interfaz de usuario en los cambios en el estado de autenticación:

  • Justo después de que el oyente ha sido registrado

  • Cuando un usuario ha iniciado sesión

  • Cuando el usuario actual está desconectado
  • Cuando el usuario actual cambia
  • Cuando hay un cambio en el token del usuario actual

Aquí algunos consejos para descubrir el estado actual:

  • Llamada de registro: salta la primera llamada con una bandera.
  • El usuario ha iniciado sesión: el usuario del parámetro es! = Nulo.
  • El usuario se desconectó: el usuario del parámetro es == nulo.
  • Cambios actuales del usuario: ¡el usuario del parámetro es! = Nulo y la última identificación del usuario es! = El ID del usuario desde el parámetro
  • Actualización del token de usuario: el usuario desde el parámetro es! = Nulo y la última identificación del usuario es == ID del usuario desde el parámetro

Este oyente es un desastre y muy bugprone. El equipo de Firebase debería investigarlo.

Cuando uso signInWithEmailAndPassword() para iniciar sesión en onAuthStateChanged() siempre se dispara dos veces.

Estoy seguro de que la escucha solo se agrega una vez a firebaseAuth, and I have the code in onStop () `para eliminar al oyente después de eso.

¿Alguien sabe como resolver esto?

Mi código:

public class SignInActivity extends BaseActivity implements View.OnClickListener, GoogleApiClient.OnConnectionFailedListener{ private static final String PREF_KEY_USER_EMAIL = "User_Email"; private static final int RC_SIGN_IN = 1111; private FirebaseAuth firebaseAuth; private FirebaseAuth.AuthStateListener authStateListener; private DatabaseReference firebaseDbReference; private TextView fieldEmail; private TextView fieldPassword; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sign_in); getSupportActionBar().hide(); firebaseAuth = FirebaseAuth.getInstance(); firebaseDbReference = FirebaseDatabase.getInstance().getReference(); fieldEmail = (TextView) findViewById(R.id.field_email); fieldPassword = (TextView) findViewById(R.id.field_password); String userSavedEmail = getPreferences(MODE_PRIVATE).getString(PREF_KEY_USER_EMAIL, ""); if(userSavedEmail != null) { fieldEmail.setText(userSavedEmail); fieldPassword.requestFocus(); } TextView linkForgotPassword; Button buttonLogin; linkForgotPassword = (TextView) findViewById(R.id.link_forgotPassword); buttonLogin = (Button) findViewById(R.id.button_Login); buttonSignUp = (Button) findViewById(R.id.button_signUp); if (linkForgotPassword != null) { linkForgotPassword.setOnClickListener(this); } if (buttonLogin != null) { buttonLogin.setOnClickListener(this); } if (buttonSignUp != null) { buttonSignUp.setOnClickListener(this); } authStateListener = new FirebaseAuth.AuthStateListener() { @Override public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { if(firebaseAuth.getCurrentUser() != null) { onAuthSuccess(firebaseAuth.getCurrentUser()); } } }; } @Override protected void onStart() { super.onStart(); firebaseAuth.addAuthStateListener(authStateListener); } @Override protected void onStop() { super.onStop(); if (authStateListener != null) { firebaseAuth.removeAuthStateListener(authStateListener); } } @Override public void onClick(View v) { switch (v.getId()){ case R.id.link_forgotPassword: forgotPassword(); break; case R.id.button_Login: emailLogin(); break; case R.id.button_signUp: emailSignUp(); break; } } @Override public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { Toast.makeText(this, "Google Play Services error.", Toast.LENGTH_SHORT).show(); } private void forgotPassword(){ FirebaseAuth auth = FirebaseAuth.getInstance(); String emailAddress = fieldEmail.getText().toString(); if(TextUtils.isEmpty(emailAddress)){ Toast.makeText(SignInActivity.this, R.string.msg_EnterEmail, Toast.LENGTH_SHORT).show(); } else { showProgressDialog(); auth.sendPasswordResetEmail(emailAddress) .addOnCompleteListener(new OnCompleteListener<Void>() { @Override public void onComplete(@NonNull Task<Void> task) { hideProgressDialog(); if (task.isSuccessful()) { Toast.makeText(SignInActivity.this, R.string.msg_ResetPasswordEmailSent, Toast.LENGTH_LONG).show(); } } }); } } private void emailLogin(){ if (!validateForm()) { return; } showProgressDialog(); String email = fieldEmail.getText().toString(); String password = fieldPassword.getText().toString(); firebaseAuth.signInWithEmailAndPassword(email, password) .addOnCompleteListener(new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { hideProgressDialog(); if (!task.isSuccessful()) { Toast.makeText(SignInActivity.this, R.string.msg_EmailLoginFailed, Toast.LENGTH_SHORT).show(); } else { // Save the email getPreferences(MODE_PRIVATE).edit() .putString(PREF_KEY_USER_EMAIL, fieldEmail.getText().toString()) .apply(); } } }); } private void emailSignUp(){ if (!validateForm()) { return; } showProgressDialog(); String email = fieldEmail.getText().toString(); String password = fieldPassword.getText().toString(); firebaseAuth.createUserWithEmailAndPassword(email, password) .addOnCompleteListener(new OnCompleteListener<AuthResult>() { @Override public void onComplete(@NonNull Task<AuthResult> task) { hideProgressDialog(); if (task.isSuccessful()) { FirebaseUser user = task.getResult().getUser(); String displayName = displayNameFromEmail(user.getEmail()); // Update profile display name. UserProfileChangeRequest profileUpdates = new UserProfileChangeRequest.Builder() .setDisplayName("Jane Q. User") .build(); user.updateProfile(profileUpdates); } else { Toast.makeText(SignInActivity.this, R.string.msg_EmailSignUpFailed, Toast.LENGTH_SHORT).show(); } } }); } private void onAuthSuccess(FirebaseUser user) { // Write new user writeNewUser(user.getUid(), user.getDisplayName(), user.getEmail(), user.getPhotoUrl()); // Go to MainActivity startActivity(new Intent(this.getApplicationContext(), MainActivity.class)); finish(); } private void writeNewUser(String userId, String displayName, String email, android.net.Uri photoUrl) { User user = new User(displayName, email); if(photoUrl != null){ user.setPhotoUrl(photoUrl.toString()); } firebaseDbReference.child("users").child(userId).setValue(user); } private String displayNameFromEmail(String email) { if (email.contains("@")) { return email.split("@")[0]; } else { return email; } } private boolean validateForm() { boolean result = true; if (TextUtils.isEmpty(fieldEmail.getText().toString())) { fieldEmail.setError("Required"); result = false; } else { fieldEmail.setError(null); } if (TextUtils.isEmpty(fieldPassword.getText().toString())) { fieldPassword.setError("Required"); result = false; } else { fieldPassword.setError(null); } return result; } }


Lejos de ser ideal también, pero es una solución más precisa.

private String authFlag = ""; ... authStateListener = new FirebaseAuth.AuthStateListener() { @Override public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { if (firebaseAuth.getCurrentUser() == null) { if (authFlag != null) { authFlag = null; subscriber.onNext(null); } } else { String uid = firebaseAuth.getCurrentUser().getUid(); if (authFlag == null || authFlag.isEmpty() || !authFlag.equals(uid)) { authFlag = uid; subscriber.onNext(firebaseAuth.getCurrentUser()); } } }


Se dispara dos veces y creo que este es un error que los chicos de Firebase deberían solucionar (mirándote a ti, Frank jejeje). Lo único que puedo pensar que puedes hacer ahora es agregar una bandera como esta.

private boolean flag = true; ... authStateListener = new FirebaseAuth.AuthStateListener() { @Override public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) { if(firebaseAuth.getCurrentUser() != null && flag) { onAuthSuccess(firebaseAuth.getCurrentUser()); flag=false; } } };

Lejos de ser ideal, pero funcionará por ahora. El código aún se dispara dos veces, aceptamos el primero y negamos el segundo con nuestra bandera, de esta forma, si los chicos de Firebase lo arreglan y de repente el oyente se ejecuta una vez, nuestro código aún funciona. Tal vez esté destinado a que el oyente corra dos veces, con suerte tendremos algunas respuestas de la publicación cruzada de Frank