0

The code looks like this:

final DatabaseReference TuidRef = usersRef.child(td);
        final DatabaseReference msgRef = TuidRef.child("rec_msg");
        final DatabaseReference FuidRef = TuidRef.child("fromUID");
        final DatabaseReference secretRef = TuidRef.child("rec_secret");


        msgRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot1) {
                ms = dataSnapshot1.getValue(String.class);
                flag++;

            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

        FuidRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot2) {
                fUid = dataSnapshot2.getValue(String.class);
                flag++;
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

        secretRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot3) {
                st = dataSnapshot3.getValue(String.class);
                flag++;

            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });

        String flagS = "" + flag;
        Log.i("flag",flagS);
        if(flag > 2)
            displayMessage();

I used the flag to know how many times the ValueEventListeners are triggered, but the flag is found to be 0, in the log.

td is the uid of the person who receives the message. In the picture below it is same as the parent key of other sibling Childs.

The database looks something like this, when there are no messages: image1

The database looks like this, when messages are received: image2

Edit: How can I execute the function displayMessage(), when all three of the listeners have been triggered at once?

The value is added simultaneously to all three of them in the firebase database, though.

1 Answers1

0

You'll never know how many times a ValueEventListeners is triggered in the way do, because the value of flag will always remain 0. This is happening due the asynchronous behaviour of onDataChange() method which is called even before you are trying to get the data from the database. What's really happening is that you are trying to get the data from the database and immediately try to log it while the flag variable has the initial value of 0. Then, when getting the data from the database completes, it changes flag's value, but it's never read again.

A quick solve for this problem would be add three different flags inside each callback and try to log then separately only inside the onDataChange() method like this:

msgRef.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot1) {
        ms = dataSnapshot1.getValue(String.class);
        flag1++;
        Log.i("flag1", String.valueOf(flag1));
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {}
});

FuidRef.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot2) {
        fUid = dataSnapshot2.getValue(String.class);
        flag2++;
        Log.i("flag2", String.valueOf(flag2));
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {}
});

secretRef.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot3) {
        st = dataSnapshot3.getValue(String.class);
        flag3++;
        Log.i("flag3", String.valueOf(flag3));
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {}
});

If you need in your code to get the value of that flag outside the onDataChange() method, I recommend you see the last part of my anwser from this post in which I have explained how it can be done using a custom callback. You can also take a look at this video for a better understanding.

Edit:

msgRef.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot1) {
        ms = dataSnapshot1.getValue(String.class);
        flag++;

        FuidRef.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot2) {
                fUid = dataSnapshot2.getValue(String.class);
                flag++;

                secretRef.addValueEventListener(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot dataSnapshot3) {
                        st = dataSnapshot3.getValue(String.class);
                        flag++;
                        Log.i("flag", String.valueOf(flag));
                    }

                    @Override
                    public void onCancelled(@NonNull DatabaseError databaseError) {}
                });
            }

            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {}
        });
    }

    @Override
    public void onCancelled(@NonNull DatabaseError databaseError) {}
});
Alex Mamo
  • 130,605
  • 17
  • 163
  • 193
  • Does this mean `displayMessage()` will never be executed? I want to execute this function when all three of them are changed, how can I do that? –  Aug 31 '18 at 09:36
  • Yes, that's correct, `displayMessage()` method will never be executed. If you want to have all flags into a single `flag`, the you should use nested listeners like in my updated answer. Does it work? – Alex Mamo Aug 31 '18 at 09:48