当我使用signInWithEmailAndPassword()
登录时,onAuthStateChanged()
总是触发两次。
我非常确定在firebaseAuth, and I have the code in
onStop()`中只添加了一次监听,之后就删除了监听。
有人知道怎么解决这个问题吗?
My code:
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;
}
}
发布于 2016-06-08 02:08:19
它确实触发了两次,我认为这是一个错误,Firebase的人应该修复(看着你,弗兰克,哈哈哈)。我认为您现在唯一能做的就是添加一个这样的标志。
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;
}
}
};
离理想还很远,但现在可以用了。代码仍然会触发两次,我们接受第一次,并用我们的标志拒绝第二次,这样如果Firebase的人修复了它,突然侦听器运行了一次,我们的代码仍然可以工作。也许它的目的是让听众运行两次,希望我们能从Frank的交叉帖子中得到一些答案
发布于 2016-11-05 17:48:45
双重调用应为注册调用。不仅如此,onAuthStateChanged将在许多不同的状态下被调用多次,不可能知道它是哪个状态。
onAuthStateChanged(FirebaseAuth身份验证)
当身份验证状态发生变化时,将在UI线程中调用此方法:
监听程序执行registered操作后的
用户在中登录时的
当前用户注销时的
当前用户更改
当当前用户的令牌发生更改时
下面是一些发现当前状态的提示:
中的user id
这个监听程序很混乱,而且很容易出错。消防队应该去调查一下。
发布于 2016-07-04 18:33:43
也远不是理想的,而是更精确的解决方案。
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());
}
}
}
https://stackoverflow.com/questions/37674823
复制相似问题