Firebase onChildAdded在更新子

时间:2017-09-26 10:33:03

标签: android firebase firebase-realtime-database

我正在尝试执行一些基本的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);

在我的熟食订单列表中,当用户点击订单时,它意味着将熟标志更新回“假”并出现在未熟化订单列表中。它使用以下setValue()方法完成。

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

第1期

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

当我继续点击煮熟的订单时,它会按预期使用正确的数据调用onChildAdded()一次。所以从技术上讲,我错过了由于空数据而被煮熟的第一个订单。

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

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

1 个答案:

答案 0 :(得分:2)

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

  1. 订单已添加到compile 'io.realm:android-adapters:1.4.0' compile 'io.reactivex.rxjava2:rxandroid:2.0.1' compile 'io.reactivex:rxandroid:1.1.0' compile 'io.reactivex:rxjava:1.1.3' compile 'com.squareup.retrofit2:retrofit:2.3.0' compile 'com.squareup.retrofit2:converter-gson:2.3.0' compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0' compile 'com.squareup.okhttp3:okhttp:3.9.0' \orders已被调用,但由于其onChildAdded属性为cooked,因此为空。
  2. false属性设置为Cookedfalse会按您需要的顺序调用。
  3. 也许这不是你做的,而是它是如何在幕后实施的。也许你可以使用onChildUpdated