【发布时间】:2021-12-24 09:59:04
【问题描述】:
我的 android studio 应用程序中有一个带有 signOut 按钮的片段,该按钮应该让用户退出他的帐户,然后将他重定向回登录页面。到目前为止,我已经尝试了几件事,并查看了我能找到的每个线程,但没有任何效果。没有错误,只是没有反应。
我尝试的第一件事是:
public class PreferenceFragment extends Fragment {
private PreferenceViewModel preferenceViewModel;
private FragmentPreferenceBinding binding;
private Button btnSignOut;
private FirebaseAuth auth;
private FirebaseAuth.AuthStateListener authListener;
public View onCreateView(@NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
preferenceViewModel =
new ViewModelProvider(this).get(PreferenceViewModel.class);
auth = FirebaseAuth.getInstance();
View view = inflater.inflate(R.layout.fragment_preference, container, false);
btnSignOut = (Button) view.findViewById(R.id.sign_out);
binding = FragmentPreferenceBinding.inflate(inflater, container, false);
View root = binding.getRoot();
final TextView textView = binding.textPreference;
preferenceViewModel.getText().observe(getViewLifecycleOwner(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
textView.setText(s);
}
});
authListener = new FirebaseAuth.AuthStateListener() {
@Override
public void onAuthStateChanged(@NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = auth.getCurrentUser();
if (user == null) {
// user auth state is changed - user is null
// launch login activity
startActivity(new Intent(getActivity(), LoginActivity.class));
getActivity().finish();
}
}
};
btnSignOut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
auth.signOut();
}
});
return root;
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
@Override
public void onStart() {
super.onStart();
auth.addAuthStateListener(authListener);
}
@Override
public void onStop() {
super.onStop();
if (authListener != null) {
auth.removeAuthStateListener(authListener);
}
}
}
这是我的登录活动:
public class LoginActivity extends AppCompatActivity {
private EditText inputEmail, inputPassword;
private FirebaseAuth auth;
private ProgressBar progressBar;
private Button btnSignup, btnLogin, btnReset;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Get Firebase auth instance
auth = FirebaseAuth.getInstance();
if (auth.getCurrentUser() != null) {
startActivity(new Intent(LoginActivity.this, MainActivity.class));
finish();
}
// set the view now
setContentView(R.layout.activity_login);
inputEmail = (EditText) findViewById(R.id.email);
inputPassword = (EditText) findViewById(R.id.password);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
btnSignup = (Button) findViewById(R.id.btn_signup);
btnLogin = (Button) findViewById(R.id.btn_login);
btnReset = (Button) findViewById(R.id.btn_reset_password);
//Get Firebase auth instance
auth = FirebaseAuth.getInstance();
btnSignup.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(LoginActivity.this, SignupActivity.class));
}
});
btnReset.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(LoginActivity.this, ResetPasswordActivity.class));
}
});
btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String email = inputEmail.getText().toString();
final String password = inputPassword.getText().toString();
if (TextUtils.isEmpty(email)) {
Toast.makeText(getApplicationContext(), "Enter email address!", Toast.LENGTH_SHORT).show();
return;
}
if (TextUtils.isEmpty(password)) {
Toast.makeText(getApplicationContext(), "Enter password!", Toast.LENGTH_SHORT).show();
return;
}
progressBar.setVisibility(View.VISIBLE);
//authenticate user
auth.signInWithEmailAndPassword(email, password)
.addOnCompleteListener(LoginActivity.this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
// If sign in fails, display a message to the user. If sign in succeeds
// the auth state listener will be notified and logic to handle the
// signed in user can be handled in the listener.
progressBar.setVisibility(View.GONE);
if (!task.isSuccessful()) {
// there was an error
if (password.length() < 6) {
inputPassword.setError(getString(R.string.minimum_password));
} else {
Toast.makeText(LoginActivity.this, getString(R.string.auth_failed), Toast.LENGTH_LONG).show();
}
} else {
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
}
});
}
});
}
}
首先,我认为可能是 signOut() 没有按预期工作或自动让我重新登录。但是,如果我将 signOut() 放入 MainActivity 的 onStop() 方法中它正在工作,显然只有当我关闭应用程序时:
@Override
public void onStop() {
super.onStop();
FirebaseAuth.getInstance().signOut();
}
然后我认为程序可能没有调用相同的 FirebasAuth 实例,所以我尝试从 MainActivity 调用 FirebaseAuth 实例以达到相同的效果:
(MainActivity)getActivity()).auth.signOut();
我尝试了其他一些方法,例如将 authListener 放入 MainActivity 或删除在 LoginActivity 开始时调用 FirebasAuth 实例的代码,效果始终相同。也许它与我的 startActivity 有关,但我不确定如何以不同的方式进行。提前感谢您的帮助。
【问题讨论】:
-
如果您对使用干净的 Firebase 身份验证感兴趣,那么我建议您阅读以下文章,How to create a clean Firebase authentication using MVVM?。
-
我确实阅读了它并以类似的方式更新了我的项目。问题似乎出在我片段中的按钮上。我试过调试它,似乎我的注销按钮实际上从未执行指定的操作,在我的情况下,从 main 调用 signOut 方法。它只是卡在一个循环中,然后就停止了。
-
确保您的按钮功能齐全。
标签: java firebase android-studio firebase-authentication fragment