Firebase数据库数据快照

时间:2017-05-06 19:15:19

标签: android firebase firebase-realtime-database

我有一个firebase数据库,我可以从中保存和检索数据。我知道datasnapshotaddValueEventListener内是如何运作的。问题是只有在firebase数据库检测到其数据发生变化时才会调用或触发此操作。我只想访问数据并阅读它以便能够将它存储在arraylist或同样的东西。

我有这样的代码:

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之外做。 但我注意到这是错误的,因为只有在写入onDataChange数据库时才会调用Firebase。不应该是这种情况。

如果不调用DatabaseReference x或不使用onDataChange,我可以在DataSnapshot内循环显示值?

2 个答案:

答案 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
        }
    });

如firebase文档中所述:

  

public void addListenerForSingleValueEvent(ValueEventListener   听者)

     

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

答案 1 :(得分:0)

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

我认为您的问题在于,onDataChange方法是以异步方式调用的。这意味着您在外部执行此方法的所有操作实际上都是在调用onDataChange方法之前执行的。因此,为了了解实际情况,请参阅此post和此post。阅读这些文章,将教会您如何在Firebase中query数据以及如何retrieve data from Firebase asynchronously

希望它有所帮助。