首页 > 解决方案 > 如何在按钮的 onClickListener 中从实时数据库中获取数据

问题描述

我正在构建一个应用程序并尝试在用户按下按钮后立即获取数据。然而,数据获取部分直到 onClickListener 的 onComplete 结束后才会发生。我需要在 onComplete 结束之前访问数据。

现在,我的片段包含一个电子邮件和密码字段,他们填写并按下“登录”按钮。我在调用方法onClickListener的登录按钮上设置了一个。FirebaseAuth's signInWithEmailandPassword这将返回一个 AuthResult 任务,我将它设置为一个 onCompleteListener。

如果此任务成功,我会触发一个addListenerForSingleValueEvent()任务以从 Firebase 实时数据库中获取相关用户的数据。似乎此任务在 onComplete 方法之后运行。我该如何改变呢?我尝试为此使用 AsyncTask,但结果是一样的。

我的登录片段:

mLogInButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(final View v) {
            String email = mEmailText.getText().toString();
            String password = mPasswordText.getText().toString();
            final boolean[] loginSuccess = {false};

            Task task = mViewModel.signIn(email, 
password).addOnCompleteListener
                    (new OnCompleteListener() {
                @Override
                public void onComplete(@NonNull Task task) {
                    if (task.isSuccessful()) {
                        Log.d(TAG, "signInWithEmail:success");
                        Toast.makeText(getActivity(),
                                "Signed in!", 
Toast.LENGTH_SHORT).show();
                        loginSuccess[0] = true;
                        String uid = mViewModel.getAuth().getUid();
                        mViewModel.fetchUser(uid);
                        Log.d(TAG, mViewModel.getUser().getName());

                    } else {
                        Log.w(TAG, "signInWithEmail:failure", 
task.getException());
                        Toast.makeText(getActivity(), "Auth failed. 
Check log!",
                                Toast.LENGTH_SHORT).show();
                        loginSuccess[0] = false;
                    }
                }
            });
            //Task fetchDatabase = task.addOnCompleteListener(new 
//OnCompleteListener() {
                //@Override
                //public void onComplete(@NonNull Task task) {
                //    Log.d(TAG, "After!");
              //  }
            //}); 
//                updateUIWithDatabaseDetails(mView);
        }
    });

我的 fetchUser(uid) 及其关联的 ValueEventListener:

public void fetchUser(String uid) {
    mUserDatabase.child(uid).addListenerForSingleValueEvent(userDataValueListener);
}

public ValueEventListener userDataValueListener = new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        if (dataSnapshot.exists()) {
            Log.d(TAG, "User exists in remote!");
            mUser = dataSnapshot.getValue(User.class);
        }
        else {
            Log.d(TAG, "user doesn't exist.");
            mUser = null;
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {
        Log.d(TAG, "Can't fetch Firebase Database user:" + databaseError.getMessage());
        mUser = null;
    }
};

当前设置立即崩溃并出现 NullPointerException,Log.d(TAG, mViewModel.getUser().getName());因为数据库尚未获取用户并更新 SharedViewModel 中的用户。

底线:我认为数据库获取任务会在登录的 onClick 上的 onComplete 结束后排队执行。在 onComplete 运行时,我有什么办法可以挤进这个任务?我正在考虑使用 Handler 将其从 UI 线程中移出,但我并不真正理解它,并且确实需要一些指针。

任何帮助,将不胜感激!

标签: androidfirebase-realtime-databaseonclicklistener

解决方案


推荐阅读