2017-05-06 112 views
0

我有一个firebase数据库,我可以从中保存和检索数据。我知道datasnapshot如何在addValueEventListener内工作。问题在于,只有在firebase数据库检测到其数据更改时才会调用或触发此操作。我只想访问数据并阅读它,以便能够将其存储在数组列表或相同的事物中。Firebase数据库Datasnapshot

我有这样的代码:

public void foo(){ 
    DatabaseReference x= FirebaseDatabase.getInstance().getReference().child("x"); 

    reservations.addValueEventListener(new ValueEventListener() { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) { 
      String userID = client.getId(); 
      for(DataSnapshot snap : dataSnapshot.getChildren()){ 
       if(snap.child("someId").equals(someId)) number++; 
       if(snap.child("userID").getValue().equals(client.getId())){ 
        isAlreadyReserved = true; // if user has already reserved the item 
        alreadyReserved(); 
        break; 
       } 
       Log.e("isAlreadyReserved: ", isAlreadyReserved+""); 
       numberOfReservations++; 
      } 
     } 
     @Override 
     public void onCancelled(DatabaseError databaseError) { 

     } 
    }); 


    if(isAlreadyReserved) { 
     alreadyReserved(); 
    } 
    else if(number == numberOfCopies){ 
     // material is no longer available 
     OtherActivity.showMaterialUnavailable(); 
    } 
    else{ 
     Reservation reservation = new Reservation(); 
     reservation.setBookId(this.bookId); 
     reservation.setResID((numberOfReservations+1)+""); 
     reservation.setUserID(client.getId()); 
     String key = reservations.push().getKey(); 
     reservations.child(key).setValue(reservation); 

     Log.e("Reservations: ", "reserve successful"); 

     AlertDialog.Builder builder = new AlertDialog.Builder(this.context); 
     builder.setTitle(R.string.reservationSuccess_title) 
       .setMessage(R.string.reservationSuccess_body); 
     AlertDialog dialog = builder.create(); 
     dialog.show(); 
    } 

} 

你可以看到,里面onDataChange我只算材料,并设置一些标志,我可以推测的ValueEventListener外面做。 但我注意到这是错误的,因为仅在写入Firebase数据库时调用onDataChange。这不应该是这种情况。

如何在不调用onDataChange或不使用DataSnapshot的情况下循环访问DatabaseReference x中的值?

回答

0

如果不使用listener,则无法在DatabaseReference内循环。当我们谈论Firebase时,我们只谈论listeners。因此,要获得这些值,您需要使用侦听器,并从dataSnapshot中获取数据。

我认为你的问题在你的情况下,是onDataChange方法以异步方式调用。这意味着在方法被调用之前,你所做的所有事情都是在方法被调用之前实际执行的。所以为了理解实际发生了什么,请看这post和这个post。阅读本文后,将教你如何在Firebase中query数据以及如何retrieve data from Firebase asynchronously

希望它有帮助。

+0

谢谢!我已经解决了我的问题。我使用了一个'AsyncTask'来对Firebase实时数据库进行REST调用,并使用它来在启动它的'ValueEventListener'的'onDataChange()'方法之前预处理我需要的数据。这样,我可以在数据处理后的恰当时间调用'onDataChange()'。 – JeobMallari

+0

很高兴听到这个消息。干杯! –

0

为了得到DatabaseReference x的值,你应该使用addListenerForSingleValueEvent

x.addListenerForSingleValueEvent(new ValueEventListener() 
    { 
     @Override 
     public void onDataChange(DataSnapshot dataSnapshot) 
     { 
      //do something 
     } 

     @Override 
     public void onCancelled(DatabaseError databaseError) 
     { 
      //do something 
     } 
    }); 

的火力文档中提到:

公共无效addListenerForSingleValueEvent(ValueEventListener 听众)

在此位置为 数据中的单个更改添加监听器。该监听器将在该位置的数据值为 后触发一次。

+0

感谢您的回答,但我认为问题依然存在。这个'addListenerForSingleValueEvent'函数只有在'DatabaseReference x'在Firebase实时数据库上执行更改时才会被调用。 我需要它去像: '从实时DB'获取数据 - >'过程data' - 上实时DB'>'进行必要的修改 相反,它是这样:为了 '执行变更触发监听器 - >'从监听器获取数据 - >'处理数据' - >'在实时数据库中执行更改' – JeobMallari

+0

此事件只发生一次,并且在您设置之后,只有在数据更改后才会发生。你试过了吗? –

+0

是的,我已经尝试过。它不能解决问题。它仍然需要数据更改才能执行该过程。在执行数据更改之前,我需要先读取值。 – JeobMallari