【问题标题】:How do I pass data out of the onDataChange method? [duplicate]如何从 onDataChange 方法中传递数据? [复制]
【发布时间】:2019-02-20 05:46:45
【问题描述】:

我设置了一个布尔值来检查应用中的重复用户名。我希望布尔值根据 ValueEventListener 中的 onDataChange 的结果返回数据。这是我所拥有的:

private boolean isUsernameValid(final String username) {


    mReference = FirebaseDatabase.getInstance().getReference();
    Query query = mReference.child("users").child(username);
    ValueEventListener mListener = new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            if (dataSnapshot.exists()) {

                //create condition that would make isUsernameValid return false

            }
        }

        @Override
        public void onCancelled(@NonNull DatabaseError databaseError) {

        }
    };

    mReference.addListenerForSingleValueEvent(mListener);

    return //if that condition is not met;
}

【问题讨论】:

标签: java android firebase firebase-realtime-database


【解决方案1】:

如果您尝试执行此类操作,您将始终返回 false,因为 Firebase 是异步的,您需要根据您的连接稍等片刻,以便从 dataSnapshot() 返回任何值

private boolean isUsernameValid(final String username) {

        boolean isUsernameValid;
        mReference = FirebaseDatabase.getInstance().getReference();
        Query query = mReference.child("users").child(username);
        ValueEventListener mListener = new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if (dataSnapshot.exists()) {

                    //create condition that would make isUsernameValid return false
                     isUsernameValid = true;
                }
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        };

        mReference.addListenerForSingleValueEvent(mListener);

        return isUsernameValid //if that condition is not met;
    }

要解决此问题,您可以创建一个界面,当我们知道我们有来自 onDataChange() 的结果时会立即触发,然后您可以从那里返回任何内容

首先创建一个接口

public interface FirebaseSuccessListener {

    void onDataFound(boolean isDataFetched);

}

然后我们只需执行您的方法来检查用户是否存在

private void isUsernameValid(final String username, FirebaseSuccessListener dataFetched) {


            mReference = FirebaseDatabase.getInstance().getReference();
            Query query = mReference.child("users").child(username);
            ValueEventListener mListener = new ValueEventListener() {
                @Override
                public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                    if (dataSnapshot.exists()) {

                        //here we are telling to our interface that the data has been found and then we can do anything with it outside this method
                         dataFetched.onDataFound(true);
                    }
                }

                @Override
                public void onCancelled(@NonNull DatabaseError databaseError) {

                }
            };

            mReference.addListenerForSingleValueEvent(mListener);


        }

然后我们可以调用该方法以从 onDataChange() 内部获取您的值

isUsernameValid.(new FirebaseSuccessListener() {
    @Override
    public void onCallback(boolean isDataFetched) {
        if(isDataFetched){
           //you know the value is true, here you can update or request any change for example you can do this 
            userIsOnFirebase(true);

      }else{
      userIsOnFirebase(false);
      }
    }
});


private boolean userIsOnFirebase(boolean isOnFirebase){
return isOnFirebase;
}

然后使用上述方法返回用户是否在您的数据库中。确保在调用 userIsOnFirebase 时,如果仍未获取数据,它将返回 false

【讨论】:

  • 看来我有一些关于线程的学习要做。谢谢。
  • 我强烈建议您从 udacity udacity.com/course/android-basics-networking--ud843 学习本课程
  • 谢谢。我一定会的。最后一个语法问题是否可以麻烦您:在您的第三个代码块中,该方法在何处以及如何被调用?我所拥有的看起来像这样:if (TextUtils.isEmpty(username)) { mUsernameView.setError(getString(R.string.error_field_required)); focusView = mUsernameView; } else if (!isUsernameValid(username, new FirebaseSuccessListener() { @Override public void onDataFound(boolean isDataFetched) { if (isDataFetched) { } }
  • isDataFetched 是一个布尔类型的变量,不是一个方法,如果你把 if(isDataFetched) 放在这意味着如果 isDataFetched = true 发生了什么事 else 是 false
  • 对,我不准确。我对代码块的开头感到困惑。相对于我的其他代码,我可以把它放在哪里?不知道如何解析第一条语句。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-26
  • 1970-01-01
  • 2016-02-24
  • 2021-05-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多