0

In my app I have a User class that stores user information, I save it to Firebase Realtime Database as follows:

mDbReference.child("UserData").child(getUser().getUid()).setValue(user);

Now in another part of the app I want to retrieve that User object, but the app crashes. It works if I use snapshot.getValue().toString() but I want to save it in an User object like below:

Query usernameQuery = fHelper.getDbReference().child("UserData")
                        .orderByChild("userName")
                        .equalTo(userCredentialEditText.getText().toString().trim());
    
                usernameQuery.addListenerForSingleValueEvent(new ValueEventListener() {
                    @Override
                    public void onDataChange(@NonNull DataSnapshot snapshot) {
                        User user = (User) snapshot.getValue(User.class);
                        assert user != null;
                        Log.i("Snapshot", user.getUserEmail());
                    }
    
                    @Override
                    public void onCancelled(@NonNull DatabaseError error) {
    
                    }
                });

I get this error:

2021-04-19 22:40:34.769 15372-15372/com.outwire E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.outwire, PID: 15372
    java.lang.NullPointerException: println needs a message
        at android.util.Log.println_native(Native Method)
        at android.util.Log.i(Log.java:176)
        at com.outwire.login.LoginActivity$1.onDataChange(LoginActivity.java:173)
        at com.google.firebase.database.Query$1.onDataChange(Query.java:191)
        at com.google.firebase.database.core.ValueEventRegistration.fireEvent(ValueEventRegistration.java:75)
        at com.google.firebase.database.core.view.DataEvent.fire(DataEvent.java:63)
        at com.google.firebase.database.core.view.EventRaiser$1.run(EventRaiser.java:55)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:224)
        at android.app.ActivityThread.main(ActivityThread.java:7565)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
3
  • Welcome to Stack Overflow! Make sure you include the stack trace in your question. Also your title seems to suggest that you need a tutorial on reading data from Firebase, but actually you've encountered an error. Commented Apr 19, 2021 at 21:38
  • Have you checked whether user.getUserEmail() is null? Commented Apr 19, 2021 at 21:43
  • @HenryTwist yes, all the contents of the object are null, but if I use snapshot.getValue().toString() I can print the information Commented Apr 19, 2021 at 21:47

1 Answer 1

2

When you execute a query against the Firebase Database, there will potentially be multiple results. So the snapshot contains a list of those results. Even if there is only a single result, the snapshot will contain a list of one result.

Your onDataChange needs to handle this list, even if there's only a single result, by looping over snapshot.getChildren().

So something like:

Query usernameQuery = fHelper.getDbReference().child("UserData")
        .orderByChild("userName")
        .equalTo(userCredentialEditText.getText().toString().trim());

usernameQuery.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot snapshot) {
        for (DataSnapshot userSnapshot: snapshot.getChildren()) {
            User user = userSnapshot.getValue(User.class);
            assert user != null;
            Log.i("Snapshot", user.getUserEmail());
        }
    }

    @Override
    public void onCancelled(@NonNull DatabaseError error) {
        throw error.toException(); // never ignore errors
    }
});
Sign up to request clarification or add additional context in comments.

5 Comments

Oops, that was a typo. getChildren is what you're looking for. For future reference: firebase.google.com/docs/reference/android/com/google/firebase/…
it worked perfectly, just one question. Why do I have to iterate when getting an object but not when I call getValue()?
Yikes, that was another typo. Sorry about that.
Yes I caught that one, but why is it that I dont have to iterate when using getValue with no argument?
getValue() with no arguments on a snapshot like this will just give you a string representation of the map data in there. The first level you'll see in there is the key of the child node, which is dynamic and what the for loop iterates over.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.