我正在尝试执行一些基本的Firebase操作,但是childEventListener的行为不符合预期。

我有一个餐厅订单列表,使用Firebase查询和ChildEventListener在列表中显示。该查询用于获取所有未煮熟的订单,即WHERE Cooked = false。

FirebaseDatabase mFirebaseDatabase = FirebaseDatabase.getInstance();
mDatabaseReference = mFirebaseDatabase.getReference().child(UUID + "/" + outletID + "/orders");
Query query = mDatabaseReference.orderByChild("cooked").equalTo(false);

mChildEventListener = new ChildEventListener() {
        @Override
        public void onChildAdded(DataSnapshot dataSnapshot, String s) {

            Log.e(TAG, "ChildEventListener() - onChildAdded - " + dataSnapshot.getKey());

            Order order = dataSnapshot.getValue(Order.class);
            mAdapter.addOrder(order);
        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {

            Log.e(TAG, "ChildEventListener() - onChildChanged - " + dataSnapshot.getKey());

            Order order = dataSnapshot.getValue(Order.class);
            mAdapter.updateOrder(order);
        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {

            Log.e(TAG, "ChildEventListener() - onChildRemoved - " + dataSnapshot.getKey() + ", exist - " + dataSnapshot.exists());

            Order order = dataSnapshot.getValue(Order.class);
            mAdapter.removeOrder(order);
        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

            Log.e(TAG, "ChildEventListener() - onChildMoved - " + dataSnapshot.getKey());
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {

            Log.w(TAG, "ChildEventListener : onCancelled - ", databaseError.toException());
        }
    };

    query.addChildEventListener(mChildEventListener);


这可以正常工作,并且可以提取正确的数据。

我还有另一个列表可以获取所有已煮熟的订单,即WHERE Cooked = true。我为此使用了一次事件监听器,并按预期显示了正确的数据。

Query query = mDatabaseReference.orderByChild("cooked").equalTo(true);


在我的煮熟的订单列表中,当用户点击订单时,它意味着将煮熟的标记更新回“ false”并显示在未煮熟的订单列表中。使用以下setValue()方法完成此操作。

mDatabaseReference.child(order.getPushID()).child("cooked").setValue(false);


第1期

当我加载活动并且没有未煮熟的订单时,这就是发生问题的地方。当我点击煮熟的订单时,Firebase数据库将按预期更新煮熟的标志,但是,按预期调用了onChildAdded(),但订单对象数据为空。之后,我还收到带有订单对象数据的onChildChanged调用。

当我继续执行已煮熟的订单时,它将按预期的正确数据调用一次onChildAdded()。因此,从技术上讲,由于缺少空数据,我错过了第一道菜。

如果我加载具有1个或多个未煮熟订单的活动,然后点击已煮熟的订单,则会按预期方式调用onChildAdded()并更新未煮熟订单的列表。

我尝试将setValue()更改为updateChildren(),但结果仍然相同。

最佳答案

通常,当您使用多个setValue操作编写一个对象的多个属性时,Firebase会重现此类问题。我建议以下情况:


将订单添加到\orders,将调用onChildAdded,但是由于其cooked属性为false,因此该字段为空。
Cooked属性设置为falseonChildUpdated会按照您需要的顺序调用。


也许这不是您要做的,而是在幕后实施的方式。也许您可以只使用onChildUpdated

10-08 08:14
查看更多