【问题标题】:Firebase query inside Handler处理程序中的 Firebase 查询
【发布时间】:2018-05-07 03:18:47
【问题描述】:

我正在尝试围绕(Firebase 查询)x(执行某些操作)功能包装服务。也就是说,我需要从 Firebase 检索数据,然后对于检索到的每个项目,执行某个类似下载文件的操作(它本身可以是 AsyncTask 或服务)。我的服务中有一个处理程序:

        @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        FirebaseUser user= FirebaseAuth.getInstance().getCurrentUser();
        DatabaseReference ref= FirebaseDatabase.getInstance().getReference().child("users").child(user.getUid()).child("oj_goals");
        ref.orderByChild("ojTag").addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                OjGoal goal= dataSnapshot.getValue(OjGoal.class);
                Log.d("inside onChildAdded",goal.getMe());
                data.add(goal);
            }
            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {
            }
            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {
            }
            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String s) {
            }
            @Override
            public void onCancelled(DatabaseError databaseError) {
            }
        });
        //FIXME: the below code continues to execute even if the Firebase-call has not yet completed
        //
        Intent intent= new Intent("com.example.sj.keymeasures.BAR_CHART_DATA_PREPARATION_FINISHED");
        /**
         * https://stackoverflow.com/questions/43800772/does-variable-order-matter-while-parcel-read-write-operation-in-parcelable
         */
        intent.putParcelableArrayListExtra("oj_goals",data);
        Log.d("[Handler]","sendingBroadcast with size "+data.size());
        sendBroadcast(intent);
        stopSelf(msg.arg1);
    }

现在您可以在代码中的 FIXME 中看到,我在另一端(在专用接收器内部)收到的内容是一个空列表。到目前为止,我知道这整件事是个坏主意,但是如果没有嵌套异步任务之类的奇怪东西,您将如何设计我要完成的工作(见第一段)?

【问题讨论】:

    标签: android firebase firebase-realtime-database android-asynctask


    【解决方案1】:

    很简单:加载子节点后需要执行的代码,应该在内部onChildAdded函数:

    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        FirebaseUser user= FirebaseAuth.getInstance().getCurrentUser();
        DatabaseReference ref= FirebaseDatabase.getInstance().getReference().child("users").child(user.getUid()).child("oj_goals");
        ref.orderByChild("ojTag").addChildEventListener(new ChildEventListener() {
            @Override
            public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                OjGoal goal= dataSnapshot.getValue(OjGoal.class);
                Log.d("inside onChildAdded",goal.getMe());
                data.add(goal);
                Intent intent= new Intent("com.example.sj.keymeasures.BAR_CHART_DATA_PREPARATION_FINISHED");
                intent.putParcelableArrayListExtra("oj_goals",data);
                Log.d("[Handler]","sendingBroadcast with size "+data.size());
                sendBroadcast(intent);
                stopSelf(msg.arg1);
            }
            @Override
            public void onChildChanged(DataSnapshot dataSnapshot, String s) {
            }
            @Override
            public void onChildRemoved(DataSnapshot dataSnapshot) {
            }
            @Override
            public void onChildMoved(DataSnapshot dataSnapshot, String s) {
            }
            @Override
            public void onCancelled(DatabaseError databaseError) {
                throw databaseError.toException(); // don't ignore errors
            }
        });
    }
    

    【讨论】:

    • 因此,实际建议是为每个添加的子节点发送广播,而不是对它们进行批处理并作为数组发送。否则,在接收端,最终会得到不断增长的列表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 2021-11-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多