0

In my Firebase database, I have two children let Child1, Child2. Child1 contains profile information of users as Root/Child1/Uid-User(x)/User_details. Child2 contains transactions done by users as Root/Child2/Uid-User(x)/Transaction_details. I want to retrieve user profile info of one user then transaction of the same user then store it in some object. Then profile info of another user, his transaction and store it in another object and so on. How can I do that? as Firebase methods run asynchronously so if I create one method to retrieve from Child1 and another for Child2 then they execute asynchronously and create the problem.

KENdi
  • 7,576
  • 2
  • 16
  • 31
Deepak Vajpayee
  • 348
  • 2
  • 4
  • 15

2 Answers2

0

You can retrieve it Initially by putting a listener to the userDetail node once this is done ensure retrieved data should not be null after again you make another request to retrive his transction data

Or You Retrieve the both separately and put the result into a 2 HashMap once the data retrieved from both listeners you can merge them based on the key (Ensure that the length of both map should be same)

To ensure Both the listeners are invoked you make like this

Initially put two variables

userProfileHit = 0;
userTransctionHit = 0;
privte void userList () {
userProfileHit ++;
private ValueEventListener userListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        //retriveData
        userProfileHit --;
        doMergingTask ();
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        userProfileHit --;
        doMergingTask ()
    }
};
}
private void transctionList () {
userTransctionHit ++;
private ValueEventListener transctionListener = new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        userTransctioneHit --;
        doMergingTask ()
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        userTransctionHit --;
        doMergingTask ()
    }
};
}
private void  doMergingTask () {
    if (userTransctionHit == 0 && userProfileHit == 0) {
      // Check Datas are valid and merge it
    }
}
GeekyInt
  • 393
  • 4
  • 9
  • A user can do more than one transactions therefore the number of entries in the two retrievals may differ which will lead this method to failure. – Deepak Vajpayee May 26 '17 at 09:18
0

My suggestion is that you put the method for retrieving the users transactions inside the onDataChanged method for retrieving profile information. So that, when you get the users profile information, you use it to get users transaction information and create the object. You can nest the firebase event listeners to produce the any outcome you want.

For Example:

final FirebaseDatabase database = FirebaseDatabase.getInstance();
final DatabaseReference ref = database.child("profile");

// Attach the first listener to read the data at our profile reference
ref.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        final Profile profile = dataSnapshot.getValue(Profile.class);

        DatabaseReference transactionRef = database.child("transaction");

        // Attach a listener to read the data at our transactions reference
        transactionRef.addValueEventListener(new ValueEventListener() {

        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
        Transaction transaction = dataSnapshot.getValue(Transaction.class);
        //
        //Do stuff with the Transaction object and Profile object here.
        //


        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            System.out.println("The read failed: " + databaseError.getCode());
        }
        });
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        System.out.println("The read failed: " + databaseError.getCode());
    }
});
T double
  • 349
  • 3
  • 12
  • @ T double, as I have to call method iteratively, therefore, the second call starts before completion of the first call to the method, this is creating problem. – Deepak Vajpayee May 17 '17 at 19:16
  • Yes, i understand. The second call starts before completion of the first call to the method because the second call is not inside the onDataChanged method of the first call...what happens is that firebase return data on a different tread from the activity threat so what ever you want to do with the data MUST be done only inside the onDataChanged method. You cannot try to use the data from firebase outside the onDataChanged method or you will end up with a nullpointerexception. I have added an example to my answer. i hope it helps – T double May 18 '17 at 11:11
  • You are welcome. Please mark my answer as the correct answer for this question and up vote it..thanks – T double May 19 '17 at 09:25