永远不会执行onDataChange

时间:2018-02-07 21:46:25

标签: java android firebase firebase-realtime-database

这是我的代码:

public ArrayList<Integer> getArray() {

    final FirebaseDatabase database = FirebaseDatabase.getInstance();

    final DatabaseReference myReff =database.getReference("server").child("user");


    myReff.addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            boolean connected = dataSnapshot.getValue(Boolean.class);
            if (connected){
                Log.d("CONNECT","YES");
            }
            else {
                Log.d("CONNECT","NO");

            }

            GenericTypeIndicator<ArrayList<Integer>> genericTypeIndicator = new GenericTypeIndicator<ArrayList<Integer>>() {};
            array = dataSnapshot.getValue(genericTypeIndicator) ;
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });


    return array;
}

这是我的数据库:

 "server" : {
  "user" : {
         1 : 0,
         2 : 0,
         3 : 0
 },
}

此代码的目的是检索数据库中的数组。

问题是 OnDataChange在此函数中永远不会被称为

(我调试我的代码,在其中放置断点,但没有发生。并且Logcat中没有显示CONNECT)。

我不明白为什么,因为当添加一个监听器时,即使数据没有改变,也必须至少触发一次ondatachange。

你能解释一下为什么没有执行OnDataChange吗?

3 个答案:

答案 0 :(得分:1)

当您添加ListenerForSingleValueEvent或任何其他Firebase-listener时,您的手机会启动连接到互联网的服务并在获得结果后返回结果。 当您的手机连接到firebase服务器并返回数据时,您的功能(public ArrayList<Integer> getArray())已经完成。该函数不会等待数据返回,它会继续。

最终,当您的数据从Firebase数据库返回时,它会调用函数public void onDataChange(DataSnapshot dataSnapshot)或您在function public void onCancelled(DatabaseError databaseError)

中声明的new ValueEventListener(){}

因此,在您的情况下,如果要返回数组,则需要从onDataChange(DataSnapshot dataSnapshot)函数调用另一个函数并将该数组作为参数传递。

例如:

    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        boolean connected = dataSnapshot.getValue(Boolean.class);
        if (connected){
            Log.d("CONNECT","YES");
        }
        else {
            Log.d("CONNECT","NO");

        }

        GenericTypeIndicator<ArrayList<Integer>> genericTypeIndicator = new GenericTypeIndicator<ArrayList<Integer>>() {};
        array = dataSnapshot.getValue(genericTypeIndicator);

        handleArrayFunction(array);
    }

在你的public ArrayList<Integer> getArray()函数之外声明一个像这样的新函数:

    private void handleArrayFunction(ArrayList<Integer> array){ 
        //use your array for what you want
    }

希望我能理解! 如果某些事情不够明确,请随意这样说:)

答案 1 :(得分:0)

我昨天想知道同样的问题,     看看这段代码片段如何解决问题。

逻辑是,有一些数据及其变更(更新或删除) onDataChanged 将被触发。但是当最初没有数据时,它将转到 onError

请检查代码段,我想你会找到答案。

                @Override
                public void onDataChanged() {
                    // If there are no chat messages, show a view that invites the user to add a message.
                    mBinder.progress.setVisibility(View.GONE); // tried to hide progressbar on data changed when there is no data found but didn't worked.
                    mBinder.rvChatUsersList.llNoData.setVisibility(getItemCount() == 0 ? View.VISIBLE : View.GONE);
                }

                @Override
                public void onError(@NonNull DatabaseError error) {
                    super.onError(error);
                    mBinder.progress.setVisibility(View.GONE); // tried to hide progressbar on error due to no data found and it worked.
                }

答案 2 :(得分:-1)

Just write it.

public ArrayList<Integer> getArray() {

    final FirebaseDatabase database = FirebaseDatabase.getInstance();

    final DatabaseReference myReff =database.getReference("server").child("user");

    myReff.addValueEventListener
(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            boolean connected = dataSnapshot.getValue(Boolean.class);
            if (connected){
                Log.d("CONNECT","YES");
            }
            else {
                Log.d("CONNECT","NO");
            }
            GenericTypeIndicator<ArrayList<Integer>> genericTypeIndicator = new GenericTypeIndicator<ArrayList<Integer>>() {};
            array = dataSnapshot.getValue(genericTypeIndicator) ;
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {

        }
    });
    return array;
}