1

I know this might be a common question but I am really stuck at this point.

I am receiving data from 2 multiple locations and after I received from both I need to continue executing and than return that data to the calling method.

I am aware of this thread: https://stackoverflow.com/a/33204705/1820644 but it doesn't fit here actually as I need to return the data to the calling method.

For the method that blocks UI thread I can call it from AsyncTask, there is no problem. But how can I return data to the calling method that I have successfully completed execution.

This is inside my helper class

// This method should be called in AsyncTask
public boolean doComputation() {
        DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("activity")
                .child(id);

        ref.child("path1").addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
               // Call 1 completed
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

        ref.child("path2").addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
               // Call 2 completed
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });

        // Some more to do

        // Need to return true after execution complete
        return true;
}

I can not return true inside of the onDataChange as it will counted for onDataChange method and not for doComputation.

I can perform the calculation by moving it to another method and after each onDataChange callback I can check for variable count, and if it is 2 I can perform the calculations. But after it completes I need to notify it to the calling method that execution is completed.

This is a little bit tricky with Firebase. But, I am really stuck at it right now. Any help will be much appreciated. Thank you.

Community
  • 1
  • 1
kirtan403
  • 7,293
  • 6
  • 54
  • 97
  • The solution [at this answer](http://stackoverflow.com/a/38188683/4815718) is probably more powerful and complex than you need, but may be helpful. – Bob Snyder Jul 31 '16 at 17:33
  • @qbix You find me the gold! I saw that video on launch but it was too deep to understand at that time when I didn't knew what firebase is. But, now that peace is a gold. Thank you so much! I think that may solve the problem. I'm going to try that tomorrow morning. – kirtan403 Jul 31 '16 at 19:25

3 Answers3

1

I have gone with the Tasks API which Firebase uses already. Its great.

As mentioned by @qbix , This answer does the same thing. The example in the answer explains good.

You can also find video link of this API instructions here.

I have tried and tested it. Solves my problem.

Community
  • 1
  • 1
kirtan403
  • 7,293
  • 6
  • 54
  • 97
0

Depends on the case, what I usually do is to set a flag after each listener completed its job and then call a method to check the flags. If they are all completed, then do the next operation.

For example

private Boolean listener1Completed;
private Boolean listener2Completed;

public void addListeners() {
    DatabaseReference ref = FirebaseDatabase.getInstance().getReference().child("activity")
            .child(id);

    ref.child("path1").addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
           listener1Completed = true;
           checkListenerStatus();
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {}
    });
    ref.child("path2").addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
           listener2Completed = true;
           checkListenerStatus();
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {}
    });
}

private void checkListenerStatus() {
    if (listener1Completed && listener2Completed) {
        // do computation
    }
}
Wilik
  • 7,630
  • 3
  • 29
  • 35
  • I know I can do the stuff like this, I talked about it in the question also. The main problem is how can I return the value to the calling method. – kirtan403 Jul 31 '16 at 19:24
  • @kirtan403 oh sorry, I didn't notice that. Then check out the link from qbix's comment in your question, that's an excellent solution. – Wilik Jul 31 '16 at 19:29
  • Yes, I am looking forward to that solution tomorrow morning. Its too late now! Need some sleep.. Zzz.. – kirtan403 Jul 31 '16 at 19:36
0

Since firebase works in another thread you can't return desired result instantly. You have to create callback to notify the caller when your result already received. You can achieve this using interface read here

Another way. You can get result from Asynctask Return a value from AsyncTask in Android

Or you can pass your class in parameter (not in AsyncTask job)

public void doComputation(yourCallerClass cls) {
//firebase result.....void

cls.YourResult(trueOrFalse);
.....
}

in your caller class instance eg. yourCallerClass

...
public void YourResult(boolean result){
// do stuff
}
Community
  • 1
  • 1