5

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)
Peter Haddad
  • 78,874
  • 25
  • 140
  • 134
PeakGen
  • 21,894
  • 86
  • 261
  • 463
  • Have a look at [my answer](https://stackoverflow.com/a/30912711/4916627) about linking users to their data in firebase. – André Kool Apr 24 '18 at 11:19
  • @yoAlex5 Those reference are for Cloud Firestore, while OP is using the Firebase Realtime Database. For a simple example to read from there, see https://firebase.google.com/docs/database/android/read-and-write#listen_for_value_events – Frank van Puffelen Apr 24 '18 at 13:32
  • @FrankvanPuffelen Thank you. Comment was deleted – yoAlex5 Apr 24 '18 at 13:37

3 Answers3

11

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() {..}
Peter Haddad
  • 78,874
  • 25
  • 140
  • 134
  • Thanks but aren't you downloading the entire data table? – PeakGen Apr 24 '18 at 10:47
  • 1
    Please check the edit and no you can just do `DatabaseReference reference = FirebaseDatabase.getInstance().getReference("user").child(userid);` then it will only get the data of the current logged in user which is John in this case – Peter Haddad Apr 24 '18 at 10:51
  • Thanks. I am going to check now. – PeakGen Apr 24 '18 at 10:52
  • if the answer helped you please upvote it and mark it as correct, thank you! – Peter Haddad Apr 24 '18 at 15:58
  • When I try to get the data from `DataSnapshot`, it throws a `NullPointerException`. The `OnDataChanged` is getting fired. – PeakGen Apr 25 '18 at 06:22
  • 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 – Peter Haddad Apr 25 '18 at 06:22
  • I made an edit with code, screenshots etc. Please check – PeakGen Apr 25 '18 at 06:32
  • thats because you are not using firebase authentication – Peter Haddad Apr 25 '18 at 06:35
  • 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 Apr 25 '18 at 06:36
  • 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 – Peter Haddad Apr 25 '18 at 07:31
  • 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. – PeakGen Apr 25 '18 at 08:40
  • @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()` – Ravi.Dudi Nov 15 '19 at 11:58
  • 1
    @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 – Peter Haddad Nov 15 '19 at 12:01
  • @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! – Ravi.Dudi Nov 15 '19 at 12:03
1
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) {    
                                           }
                           });
Levon Petrosyan
  • 8,815
  • 8
  • 54
  • 65
0

You have to collect the response from firebase to somePOJO Class

follow link : https://firebase.google.com/docs/database/admin/retrieve-data

As you can see in onDataChange() the response is collected in Post.class which is POJO class.

Ritesh
  • 533
  • 2
  • 7
  • 18