【问题标题】:Firebase signOut() method or AuthListener not working as intendedFirebase signOut() 方法或 AuthListener 未按预期工作
【发布时间】: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


【解决方案1】:

我遇到了和你一样的问题,我通过简单地删除让你在 LoginActivity 中自动登录的三行代码解决了这个问题:

if (auth.getCurrentUser() != null) {
        startActivity(new Intent(LoginActivity.this, MainActivity.class));
        finish();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-22
    • 2015-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多