0

Hi I am trying to create an social media type app that has a User class. And I need to retrieve the user data from the Firebase realtime database and store it as private attributes in the class. Currently I have tried this code in my user class:

public class User {
private String uID;
private String name;
private String email;
private DatabaseReference mdatabaseReference;

public User(String givenUiD){

    this.uID =givenUiD;
    mdatabaseReference= FirebaseDatabase.getInstance().getReference();
    mdatabaseReference.child("users").child(givenUiD).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
            name=dataSnapshot.child("name").getValue(String.class);
            email = dataSnapshot.child("email").getValue(String.class);
            Log.d(TAG, "onDataChange: "+name);
        }

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

        }
    });

    public String getName(){
        return this.name;
    }
    
}

And this is the section of code I run in the signInFragment:

currentUser=new User(mAuth.getCurrentUser().getUid());
Log.d(TAG, "onComplete: )"+currentUser.getName());
Toast.makeText(getContext(),"Log in successful.Welcome"+currentUser.getName(),Toast.LENGTH_SHORT).show();

However, the issue is that inside the onDataChange fuction, the logcat displays the correct 'name' of the user from the database. However when I try to return the name using the getName() method, the name shows up as null. I think the issue is name=dataSnapshot.child("name").getValue(String.class); doesn't store the value in the name attribute as I would like it to, but I'm not sure how to resolve this. Am I using dataSnapshots in completely the wrong way? Help would be much appreciated, thankyou.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
yt.
  • 327
  • 1
  • 2
  • 11
  • Data is loaded from Firebase asynchronously, which means that `onDataChange` may run seconds later than when you call `addValueEventListener`. Any code that needs the data from the database needs to be inside `onDataChange` or be called from there. For more on this, see the questions I linked. – Frank van Puffelen Nov 20 '21 at 22:16
  • @FrankvanPuffelen Thankyou for the questions you linked. I understand the asynchronous nature now but I am still very confused, is it still possible to return `name` from the User class? I tried adding this line of code from the first answer `System.out.println("loaded "+name);` – yt. Nov 20 '21 at 23:24
  • Yes, it is possible to return it - but only **after** the `onDataChange` has run. If you're not getting the expect result from `getName`, check your logcat - because likely the `Log.d(TAG, "onDataChange: "+name);` won't have shown then. – Frank van Puffelen Nov 21 '21 at 00:10
  • There is no way you can do that. Firebase API is asynchronous. You might also be interested in reading this article, [How to read data from Firebase Realtime Database using get()?](https://medium.com/firebase-tips-tricks/how-to-read-data-from-firebase-realtime-database-using-get-269ef3e179c5). – Alex Mamo Nov 21 '21 at 10:42

0 Answers0