Android + Firebase: synchronous for into an asynchronous function

前端 未结 1 422
粉色の甜心
粉色の甜心 2021-01-26 18:58

I\'m making a function (Java - Android) which should return me a list of objects filled with data from Firebase. My problem is that I need to send the result to the listener jus

相关标签:
1条回答
  • 2021-01-26 19:11

    Something that is asynchronous cannot reliably be made synchronous on Android. Whenever you feel the urge to do that, take a deep breath and repeat that first sentence. Or read my answer here: Setting Singleton property value in Firebase Listener

    Instead you will have to do what everyone does: move the code that needs the data into the callback that is triggered when the data is available.

    In your case it is a bit trickier, since you're loading multiple items. Luckily though you know how many items you need to load. So if you introduce a counter to track how many items have loaded, you will know when you're done:

    final DatabaseReference beaconMessageRef = dataSnapshot.getRef().getRoot().child("region_messages/" + regionKey);
    beaconMessageRef.addListenerForSingleValueEvent(new ValueEventListener() {
      @Override
      public void onDataChange(DataSnapshot dataSnapshot) {
        if(!dataSnapshot.exists())
          FirebaseHelper.this.messageByBeaconListener.onSuccess(null);
    
        for (DataSnapshot regionMessageDS : dataSnapshot.getChildren()) {
    
          RegionMessage regionMessage = regionMessageDS.getValue(RegionMessage.class);
          String msgKey = regionMessageDS.getKey();
    
          final Integer[] counter = new Integer[1];
          final DatabaseReference messageRef = regionMessageDS.getRef().getRoot().child("messages/"+msgKey);
          messageRef.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot innerSnapshot) {
              if(innerSnapshot.exists()){
                Message msg = innerSnapshot.getValue(Message.class);
                FirebaseHelper.this.addMessageByBeacon(msg);
              }
              counter[0] = new Integer(counter[0].intValue()+1);
              if (counter[0].equalTo(dataSnapshot.numChildren()) {
                List<Message> msgs = FirebaseHelper.this.beaconMessageList;
                FirebaseHelper.this.beaconMessageList = null;
                FirebaseHelper.this.messageByBeaconListener.onSuccess(msgs);
              }
            }
    
            @Override
            public void onCancelled(DatabaseError databaseError) {
              FirebaseHelper.this.messageByBeaconListener.onFail(databaseError);
            }
          });
        }
      }
    
      @Override
      public void onCancelled(DatabaseError databaseError) {
        FirebaseHelper.this.messageByBeaconListener.onFail(databaseError);
      }
    });
    

    See this answer for an explanation of the single-element-array: https://stackoverflow.com/a/5977866/209103

    0 讨论(0)
提交回复
热议问题