0

I have a class UserName which has been created for the purpose of returning the userName when provided with userID. The problem is that I can't change the instance variable userName inside the anonymous class ValueEventListener. The Log.i() function inside the anonymous class successfully prints the correct userName but while returning the variable through getUserName() function it returns empty string variable. How can I change such instance variables inside any anonymous classes ?

public class UserName {
    String userName;
    public UserName(String userID){
        DatabaseReference dbRefUsers = FirebaseDatabase.getInstance().getReference("Users");
        Query queryGetUserName = dbRefUsers.orderByChild("userID").equalTo(userID);
        queryGetUserName.addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
                if(dataSnapshot.exists()){
                    for(DataSnapshot dataSnapshotCurrent: dataSnapshot.getChildren()){
                        User userCurrent = dataSnapshotCurrent.getValue(User.class);
                        userName = userCurrent.getName();
                        Log.i("userName",userName);
                    }
                }
            }
            @Override
            public void onCancelled(@NonNull DatabaseError databaseError) {

            }
        });
    }
    public String getUserName() {
        return userName;
    }
}
  • 2
    This looks to be a possible [XY Problem](http://xyproblem.info) type question as I don't think that the problem is with your not being able to change userName since instance variables *can* be changed within inner classes, anonymous or otherwise, and your code looks to be doing this, but perhaps the problem here is your calling `getUserName()` **before** it has been changed since it is changed within a call-back method. Please post more information about how you're using this code and when exactly you call `getUserName()` – Hovercraft Full Of Eels Dec 09 '19 at 15:15
  • @HovercraftFullOfEels I am using this code in my activities as `userName = new UserName(userID).getUserName();` – Sagar Singh Bhandari Dec 09 '19 at 16:37
  • And as I explained, that is why your code is not working. The user name is changed in a ***call-back*** method, meaning it does not happen immediately and may not happen at all, only if the event that triggers the call-back occurs. You had best read up on call-back methods since you appear to not understand how they work and how this has bearing on your code. – Hovercraft Full Of Eels Dec 09 '19 at 16:41
  • Read on what triggers the FireBase database to call the `onDataChange(...)` method. ***This*** is when your call-back method is fired. – Hovercraft Full Of Eels Dec 09 '19 at 16:45
  • So how can I create a class which if I call in my activities would return me correct userName when it is provided with appropriate userID ? – Sagar Singh Bhandari Dec 09 '19 at 17:01

1 Answers1

1

The code should work, if you call getUserName AFTER you call your onDataChange method.

Here is an example illustrating that it works using a JButton and an ActionListener

public class UserName {
    private String userName;
    private JButton button = new JButton();

    public UserName() {
        button.addActionListener(e -> userName = "bob");
    }

    public String getUserName() {
        return userName;
    }
}

If I do

UserName userName = new UserName();
System.out.println(userName.getUserName());

It prints null.

But if I do

UserName userName = new UserName();
userName.getButton().doClick();
System.out.println(userName.getUserName());

Then it prints "bob"

So your issue can be that:

  • you call getUserName before onDataChange,
  • or your onDataChange method does not set the value because it does not go into the if statement or that your dataSnapshot.getChildren() is empty,
  • or even that the userName of the user in the last child is an empty String (Note that your code always returns the userName on the last child, is that inteded?)
Bentaye
  • 9,403
  • 5
  • 32
  • 45
  • The retrieving of data is not a problem as when I am using `Log.i("userName",userName);` inside the `ValueEventListener`it successfully prints the right userName but when when I called `getUserName()` function it returns empty String variable. I use this code in my activities as `userName = new UserName(userID).getUserName();` and I am assuming that since I am calling the `UserName()` constructor first and then the `getUserName()` function I should get the correct userName which I am able to print through `Log.i()` function. – Sagar Singh Bhandari Dec 09 '19 at 16:49
  • Sorry I wasn't aware about the working of call-back methods. I couldn't figure that the problem with my code was due to the sequence in which the code is being executed. Thanks for your help and time. – Sagar Singh Bhandari Dec 09 '19 at 17:40