Android: Retrieve data of a specific user from a Firebase database

20,323

Solution 1

You need to do the query:

orderByChild("FirstName").equalTo(name);
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("user");

reference.orderByChild("firstName").equalTo(name).addListenerForSingleValueEvent(new ValueEventListener() {
 @Override
public void onDataChange(DataSnapshot dataSnapshot) {
for(DataSnapshot datas: dataSnapshot.getChildren()){
   String familyname=datas.child("familyName").getValue().toString();
    }
 }
   @Override
public void onCancelled(DatabaseError databaseError) {
  }
 });

Assuming you have this database:

user
  randomid
     firstName: John
     familyName: familyName_here

Another way is to use the userid to be able to retrieve the data, but as I see in the question you are saving a random id using push().

You need to retrieve the userid:

FirebaseUser user=FirebaseAuth.getInstance().getCurrentUser();
String userid=user.getUid();

then add it to the database:

 myRef.child(userid).setValue(user);

then to retrieve data only for John:

FirebaseUser user=FirebaseAuth.getInstance().getCurrentUser();
String userid=user.getUid();
DatabaseReference reference = FirebaseDatabase.getInstance().getReference("user");
reference.child(userid).addListenerForSingleValueEvent(new ValueEventListener() {..}

Solution 2

Query specific_user = myRef.child(FirebaseAuth.getInstance().getCurrentUser().getUid());
      specific_user.addListenerForSingleValueEvent(
              new ValueEventListener() {
              @Override
              public void onDataChange(DataSnapshot dataSnapshot) {
                     //here you will get the data
                  }

              @Override
              public void onCancelled(DatabaseError databaseError) {    
                                           }
                           });
Share:
20,323
PeakGen
Author by

PeakGen

CTO

Updated on May 31, 2020

Comments

  • PeakGen
    PeakGen almost 4 years

    I am trying to read "specific" data from my firebase realtime database. I have seen examples of getting all data from a table and going through it to find the data record you want, but that is definitly not a recommended safe practice.

    Below is how I save my data

    private void saveInDatabase(String email)
        {
            // Write a message to the database
            FirebaseDatabase database = FirebaseDatabase.getInstance();
            DatabaseReference myRef = database.getReference("user");
            String key = myRef.push().getKey();
    
            User user = new User();
            user.setCountry("United States");
            user.setEmail(email);
            user.setFirstName("John");
            user.setLastName("Doh");
            user.setGender("Male");
    
            myRef.child(key).setValue(user);
    
        }
    

    Well that works great. But now I need to retrieve the data record from the user table, that is only belong to John. If I do this with MySQL, it will be smething like select * from user where primaryKey =JOHN_PRYMARY_KEY

    I gave it a try, check below.

    database.getReference("user" + FirebaseAuth.getInstance().getCurrentUser().getUid());
    

    I am really not sure how I can proceed from here, I see no method to go forward. Please advice.

    UPDATE

    I tried the answers from peter haddad and others. When I try to get the data from DataSnapshot, it throws a NullPointerException. The OnDataChanged is getting fired. Below is my database.

    enter image description here

    I tried to get data in 3 different ways, check below.

    ----No 1----

    private void getUserData()
        {
            DatabaseReference reference = FirebaseDatabase.getInstance().getReference("user");
    
            reference.orderByChild("email").equalTo(FirebaseAuth.getInstance().getCurrentUser().getEmail()).addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot dataSnapshot) {
                    for(DataSnapshot datas: dataSnapshot.getChildren()){
                        String familyname=datas.child("familyName").getValue().toString();
                    }
                }
                @Override
                public void onCancelled(DatabaseError databaseError) {
                }
            });
        }
    

    ----No 2----

    private void getUserData()
    {
        FirebaseUser user=FirebaseAuth.getInstance().getCurrentUser();
        String userid=user.getUid();
        DatabaseReference reference = FirebaseDatabase.getInstance().getReference("user");
        reference.child(userid).addListenerForSingleValueEvent(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {
                String email = dataSnapshot.getValue(User.class).getEmail();
                String firstName = dataSnapshot.getValue(User.class).getFirstName();
                Log.d("Datasnapshot",email+" "+firstName);
            }
    
            @Override
            public void onCancelled(DatabaseError databaseError) {
    
            }
        });
    }
    

    ----No 3----

    private void getUserData() {
        FirebaseDatabase database = FirebaseDatabase.getInstance();
        DatabaseReference myRef = database.getReference("user");
    
        Query specific_user = myRef.child(FirebaseAuth.getInstance().getCurrentUser().getUid());
        specific_user.addListenerForSingleValueEvent(
                new ValueEventListener() {
                    @Override
                    public void onDataChange(DataSnapshot dataSnapshot) {
                        //here you will get the data
                        String email = dataSnapshot.getValue(User.class).getEmail();
                        String firstName = dataSnapshot.getValue(User.class).getFirstName();
                        Log.d("Datasnapshot", email + " " + firstName);
                    }
    
                    @Override
                    public void onCancelled(DatabaseError databaseError) {
    
    
    
                    }
                });
    }
    

    This is the error I get. Based on the codeset I use, the place where the Null pointer trigger get different, the normal behavior.

    rebaseauth D/NetworkSecurityConfig: No Network Security Config specified, using platform default
    04-25 11:49:46.340 31202-31271/com.example.yohan.firebaseauth V/FA: Inactivity, disconnecting from the service
    04-25 11:49:47.793 31202-32166/com.example.yohan.firebaseauth W/PersistentConnection: pc_0 - Using an unspecified index. Consider adding '".indexOn": "email"' at user to your security and Firebase Database rules for better performance
    04-25 11:49:47.794 31202-31202/com.example.yohan.firebaseauth D/AndroidRuntime: Shutting down VM
    04-25 11:49:47.794 31202-31202/com.example.yohan.firebaseauth E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                    Process: com.example.yohan.firebaseauth, PID: 31202
                                                                                    java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference
                                                                                        at com.example.yohan.firebaseauth.MainActivity$6.onDataChange(MainActivity.java:249)
                                                                                        at com.google.firebase.database.Query$1.onDataChange(Unknown Source)
                                                                                        at com.google.android.gms.internal.zzbmz.zza(Unknown Source)
                                                                                        at com.google.android.gms.internal.zzbnz.zzYj(Unknown Source)
                                                                                        at com.google.android.gms.internal.zzboc$1.run(Unknown Source)
                                                                                        at android.os.Handler.handleCallback(Handler.java:751)
                                                                                        at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                        at android.os.Looper.loop(Looper.java:154)
                                                                                        at android.app.ActivityThread.main(ActivityThread.java:6682)
                                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                                        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)
    
  • PeakGen
    PeakGen about 6 years
    Thanks but aren't you downloading the entire data table?
  • Peter Haddad
    Peter Haddad about 6 years
    Please check the edit and no you can just do DatabaseReference reference = FirebaseDatabase.getInstance().getReference("user").child(us‌​erid); then it will only get the data of the current logged in user which is John in this case
  • PeakGen
    PeakGen about 6 years
    Thanks. I am going to check now.
  • Peter Haddad
    Peter Haddad about 6 years
    if the answer helped you please upvote it and mark it as correct, thank you!
  • PeakGen
    PeakGen about 6 years
    When I try to get the data from DataSnapshot, it throws a NullPointerException. The OnDataChanged is getting fired.
  • PeakGen
    PeakGen about 6 years
    When I try to get the data from DataSnapshot, it throws a NullPointerException. The OnDataChanged is getting fired.
  • Peter Haddad
    Peter Haddad about 6 years
    Are you getting the data, the same as in the answer and do you also have the same database as in the answer? Also check if you User or user node in the database to add the right one in the reference
  • Levon Petrosyan
    Levon Petrosyan about 6 years
    Can you please add the log and the code how are yoy trying to get data from dataSnapshot?
  • PeakGen
    PeakGen about 6 years
    I made an edit with code, screenshots etc. Please check
  • PeakGen
    PeakGen about 6 years
    I made an edit with code, screenshots etc. Please check
  • Peter Haddad
    Peter Haddad about 6 years
    thats because you are not using firebase authentication
  • Peter Haddad
    Peter Haddad about 6 years
    As I said in the answer, in your database you are adding random ids using push() then when you want to read the data, you are using FirebaseUser user=FirebaseAuth.getInstance().getCurrentUser(); String userid=user.getUid(); userid which is not in the database. You need to first add it to the database then you will be able to use it in query or you will get null point exception as what is happening. First retrieve the userid =>add it to the database=>use it in query to read values inside of it
  • Peter Haddad
    Peter Haddad about 6 years
    You are not adding the uid, the id is a random id. Whenever an id has - in the beginning it means this is a random id and not a user id
  • PeakGen
    PeakGen about 6 years
    Well, reference.orderByChild("firstName"). code set is the one which worked. The other code sets gave the same errors. Thanks a lot for the help.
  • Ravi.Dudi
    Ravi.Dudi over 4 years
    @PeterHaddad found the issue. problem is with String familyname = datas.child("familyName").getValue().toString() this line as when the dataSnapshot object contains only 1 users info then applying for loop on that will break the values of that object into key-value pair. so don't apply the for loop and just extract the data using String familyname = dataSnapshot.child("familyName").getValue().toString()
  • Peter Haddad
    Peter Haddad over 4 years
    @Ravi.Dudi if you have the userId you dont have to loop, but here in this question OP had a random id and didnt have the value of it thats why I added for loop
  • Ravi.Dudi
    Ravi.Dudi over 4 years
    @PeterHaddad i guess everyone who reads the answer thinks that the loop is necessary that's why even "PeakGen" was getting the NullException and so did i. But anyway thanks for the answer. cheers!