2

My Firebase Realtime Database has been built by loading an object of the Java class HashMap. In my Android Studio app I'm trying to write a method that takes a String (the key) as input, searches through the database and if the string is found it returns the associated Float (the value), otherwise it returns 0. How can I do this? Any help would be really appreciated!

EDIT: I've tried to follow the suggestions, adapting them to my particular case, but I didn't manage to solve the problem yet.
I wrote the following code in MainActivity:

DatabaseReference myRef;
Float tempValue;

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    myRef = FirebaseDatabase.getInstance().getReference("myRoot");
    tempValue=0f;
    ...
}

public void retrieveValueFromDatabase(String childName, final MainActivity activity){
    myRef.child(childName).addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            Float value=dataSnapshot.getValue(Float.class);
            if (value==null){
                value=0f;
            }
            activity.tempValue=value;
            //First Toast
            //Toast.makeText(activity,"tempValue = "+tempValue.toString(), Toast.LENGTH_LONG).show();
        }
        @Override
        public void onCancelled(DatabaseError databaseError) {
            throw databaseError.toException();
        }
    });
}

public void useValues(){
    retrieveValueFromDatabase(childName,this);
    //Second Toast
    //Toast.makeText(this,"tempValue = "+tempValue.toString(), Toast.LENGTH_LONG).show();
    //code using tempValue from here
    ...
}

If I uncomment the first toast, the correct value inside tempValue is shown, but if I uncomment the second toast, the value of tempValue shown is the default one (0.0). What am I missing?

I'm D.
  • 35
  • 7
  • Have you read the documentation and followed along with the sample code? https://firebase.google.com/docs/database/admin/retrieve-data – Doug Stevenson Mar 21 '20 at 19:15
  • @DougStevenson I've tried to use the guide you linked and the answer from Peter Haddad, but I didn't manage to make it work anyway. I've edited my question by adding the code I'm using in order to understand where my mistake is! Any help would be appreciated! – I'm D. Mar 23 '20 at 10:27

1 Answers1

1

You need to use addValueEventListener to retrieve data from the database:

DatabaseReference ref = FirebaseDatabase.getInstance().getReference("myRoot").orderByChild("name").equalTo("peter");
ref.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        Log.i("Database", dataSnapshot.child("floatValue").getValue(Long.class));
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        throw databaseError.toException();
    }
})

Here, you add a reference to the root node, then query using equalTo() to check if name = peter exists in the database and return the float value.

You should read the guide:

https://firebase.google.com/docs/database/android/read-and-write

Peter Haddad
  • 78,874
  • 25
  • 140
  • 134
  • I've already read the guide you linked, but few things are not clear to me: 1) I don't get why I have to add listeners with onDataChange and onCancelled methods even if I only need to read programmatically those values and I'm not planning to change/delete those data. Is there a reason behind this? Is the first method called even if I don't change the data? 2) I need to pass the float values to another method, not to simply log it, and since the `onDataChange` method is void, it's not immediate how to use it to obtain what I need. How would you suggest me to solve this? – I'm D. Mar 21 '20 at 20:31
  • 1) The only way to retrieve the data is to use the ValueEventListener which contains the methods onDataChange and onCancelled., the onDataChange will retrieve the data. 2) you can retrieve the value then call a method inside onDataChange after retrieving the value and pass the value as an argument to the method – Peter Haddad Mar 21 '20 at 20:42
  • Following your suggestion, I can log/print the correct value of the child while being in the OnDataChange method, but I didn't manage to pass this value and use it in another method. I've added the code I'm using to the question. Any help to spot the mistake would be appreciated! – I'm D. Mar 23 '20 at 10:43
  • where are u passing to a different method? – Peter Haddad Mar 23 '20 at 10:47
  • should be like this `myRef.child(childName).addListenerForSingleValueEvent(new ValueEventListener() { @Override public void onDataChange(DataSnapshot dataSnapshot) { Float value=dataSnapshot.getValue(Float.class); if (value==null){ value=0f; } activity.tempValue=value; getData(value); //First Toast //Toast.makeText(activity,"tempValue = "+tempValue.toString(), Toast.LENGTH_LONG).show(); } });` – Peter Haddad Mar 23 '20 at 10:48
  • The problem is that ideally I need to use the retrieved value in the same method where I call the `retrieveValueFromDatabase` method. Referring to the above code, within the `useValues` method I first call the `retrieveValueFromDatabase` method and then I need to use the retrieved value. In order to do so I've added an attribute `tempValue` to my MainActivity class, I've saved the retrieved value during the execution of `OnDataChange` and I would like to access that attribute in the `useValues` method after the call of `retrieveValueFromDatabase`. – I'm D. Mar 23 '20 at 11:08
  • you cant since ondatachange is asychronous, all the data you are using inside ondatachange can only be used there or you need to do this https://stackoverflow.com/questions/47847694/how-to-return-datasnapshot-value-as-a-result-of-a-method – Peter Haddad Mar 23 '20 at 11:13