2017-05-06 111 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