2017-09-26 66 views
0

我试图做一些基本的Firebase操作,但是childEventListener的行为并不像预期的那样。Firebase onChildAdded返回空数据,然后在更新子代后返回onChildChanged

我有一个使用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); 

这工作正常,它将正确的数据拉出。

我有另一个列表,获取所有的订单,即煮熟,即熟=真。我为此使用了一次性事件侦听器,并按预期显示了正确的数据。

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

在我熟的订单列表中,当一个数量级的用户水龙头,它的目的是更新熟旗回“假”,并出现在未煮熟的订单列表。它使用下面的setValue()方法完成。

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

问题1

当我加载活性,并且没有未煮熟的订单,这是发生问题。当我点击已订购的订单时,Firebase数据库会按预期更新cooked标志,但是,onChildAdded()按预期调用,但订单对象数据为空。之后,我还通过订单对象数据获取onChildChanged调用。

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

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

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

回答

2

通常,使用几个setValue操作编写一个对象的多个属性时,Firebase会再现这样的问题。我建议以下情形:

  1. 订单添加到\ordersonChildAdded被调用,但这是因为它的cooked属性为false空。
  2. Cooked属性设置为falseonChildUpdated将根据您的需要进行调用。

也许这不是你所做的,而只是它如何在引擎盖下实现。也许你可以使用onChildUpdated

+0

我想我可以在onChildChanged中做些事情,但我不明白为什么onChildAdded没有我的数据,因为听众正在寻找未煮熟的订单。随后的setValue()调用按预期方式工作,但在没有未煮熟的订单时不会第一次调用。 – Daan

+0

仅仅因为第一次查询处理在Firebase SDK中以不同方式实现。 –