12

I want to read specific data from firebase database. What I am currently doing is here.

DatabaseReference database = FirebaseDatabase.getInstance().getReference();
DatabaseReference myRef = database.child("profiles/");

myRef.child(phoneNo).addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        user = dataSnapshot.getValue(User.class);
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {}

});

enter image description here

Method to write to DB

public void writeToDBProfiles(Object data,String phoneNo) {
    DatabaseReference database = FirebaseDatabase.getInstance().getReference();
    DatabaseReference myRef = database.child("profiles/" + phoneNo);
    myRef.setValue(data);
}

But its returning null... Any help will be appreciated.

Reaz Murshed
  • 23,691
  • 13
  • 78
  • 98
Hassan Niazi
  • 330
  • 2
  • 3
  • 13
  • Do you have read permission to the data? See http://stackoverflow.com/documentation/firebase/5548/how-do-i-listen-for-errors-when-accessing-the-database/22652/detect-errors-when-reading-data-on-android#t=201609302251033886091 – Frank van Puffelen Sep 30 '16 at 22:58
  • @FrankvanPuffelen the snap shot which he shares has the **default security rules banner on top** doesn't that mean that **his .write and .read are both auth != null ?** In that case if he can write then he should be able to read too as the user is authorised isn't it? Please do correct me if am wrong. – Nishant Dubey Oct 01 '16 at 01:01
  • I missed that banner, but indeed it should. The most likely problem is that the user isn't authenticated. Something that you can most easily spot if you add a simple `throw databaseError.toException()` to the `onCancelled()` and a completion listener to the `setValue()`. Both are documented on the page I linked. – Frank van Puffelen Oct 01 '16 at 01:19
  • @FrankvanPuffelen I have permission. – Hassan Niazi Oct 01 '16 at 02:57
  • 2
    OK. This is starting to feel a bit like interactive debugging, for which StackOverflow is ill-suited. Can you reproduce the problem with a hard-coded value instead of `phoneNo`? Can you reproduce it with a `User ` class that has just a single property? Can you share that minimal class? Also humor me and just put error handling code in `onCancelled()` and in your call to `setValue()`. – Frank van Puffelen Oct 01 '16 at 04:16
  • Sure, I will get back to android studio and update you on it. Thanks alot for the help. – Hassan Niazi Oct 01 '16 at 15:47
  • @FrankvanPuffelen I wanted to ask one important thing does firebase database supports that my object has a URI element? – Hassan Niazi Oct 01 '16 at 17:46

4 Answers4

18

If you want to get a specific data using a phone number then you can use a Query like this

DatabaseReference database = FirebaseDatabase.getInstance().getReference();
DatabaseReference ref = database.child("profiles");

Query phoneQuery = ref.orderByChild(phoneNo).equalTo("+923336091371");
phoneQuery.addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for(DataSnapshot singleSnapshot : dataSnapshot.getChildren()){
           user = singleSnapshot.getValue(User.class); 
        }
    }
    @Override
    public void onCancelled(DatabaseError databaseError) {
        Log.e(TAG, "onCancelled", databaseError.toException());
    }
});

I think this is the best method.

Community
  • 1
  • 1
Inducesmile
  • 2,475
  • 1
  • 17
  • 19
  • 1
    addListenerForSingleValueEvent gets called only when there is an update to the data. But what if i want to just read the data even when there is no change in the existing data??? I have one requirement where i just need to read some values from a key but with Listeners i'm not able to read it when there are no updates happening. – Shravan Kumar Nov 23 '19 at 07:52
  • Exactly. Bad answer. – Ilan Aizelman WS Mar 14 '20 at 12:37
4

Ok, I got it sorted out. the above code in the question is perfectly fine and should work . I am explaining for later users who might have the same issue due to mistakes which I made.

the singleSnapshot.getValue(User.class); was unable to cast the result to user class because when uploading the data i.e. in setValue I had my photoUrl equal to null and as a result you can see the photoUrl is not present in my child node. So what I believe is (and maybe someone want correct me on this) that my singleSnapshot.getValue method was unable to cast the result.

So for now I have omitted photoUrl from my User class and will get back to it when I will start working withe relevant module.

Thanks again everyone for all the suggestions and help.

public class User {
String name;
Uri photoURL;
String bloodGroup;
String city;
String country;
double latitude;
double longitude;
boolean availableToDonate;

// Get, set and constructors are obvious here I am just saving some space in the post
}
Hassan Niazi
  • 330
  • 2
  • 3
  • 13
0

UPDATED:

The error in your updated code is here.

myRef.setValue(data);

If you are going to add data as myRef.setValue(data) then you need to specify exactly which child is getting the data or if you want to update all children at once then you need to do Atomic data update using HashMap() and updateChildren() method.

So for specific child update the correct way is this:

myRef.child("name").setValue(data);

I encourage you to read this official firebase blog to understand how to update all children in one go using HashMap().

Do let me know if it changes anything for you.

Nishant Dubey
  • 2,802
  • 1
  • 13
  • 18
0

while giving location of database of ur firebase, u should always use that folder name in inverted commas, use DatabaseReference myRef = database.child("profiles");

instead of DatabaseReference myRef = database.child("profiles/");

Syyam Noor
  • 67
  • 10