0

I'm trying create a "read" method which will get a value from Firebase (Google server) using android studio (Java) I wrote the code below but the problem that the value[0] always returning "" as a value and not the value from the server. When Im inside the method "onDataChange",the value[0] is equal to the value from the server but outside, its back to the original value. What is wrong with my code? please help

/**
 * Return value
 *
 * @param parent
 * @param child
 * @param key
 * @return
 */
public static String read(String parent, String child, String key) {
    final String[] value = {""};
    // Get a reference to our posts
    final FirebaseDatabase database = FirebaseDatabase.getInstance();
    DatabaseReference ref = database.getReference(parent).child(child);

    // Attach a listener to read the data at our posts reference
    ref.child(key).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            String str = dataSnapshot.getValue(String.class);
            System.out.println(str);
            value[0] = str;
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            System.out.println("The read failed: " + databaseError.getCode());
        }
    });

    return value[0];
}

}

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Tal Levi
  • 363
  • 1
  • 6
  • 22

2 Answers2

1

its an asynchronous method,try something like this

    public static String read(String parent, String child, String key) {
    final String[] value = {""};
    // Get a reference to our posts
    final FirebaseDatabase database = FirebaseDatabase.getInstance();
    DatabaseReference ref = database.getReference(parent).child(child);

    // Attach a listener to read the data at our posts reference
    ref.child(key).addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            String str = dataSnapshot.getValue(String.class);
            System.out.println(str);
            value[0] = str;
            passingValue(value[0]);
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
            System.out.println("The read failed: " + databaseError.getCode());
        }
    });

    return value[0];
}

    private void passingValue(String temp){
//do something with your string

}

outside the scope of OndataChange,the value won't be retained

Venky
  • 1,929
  • 3
  • 21
  • 36
1

This is happening due the asynchronous behaviour of onDataChange() method which is called even before you are getting that data from your database. A quick fix would be to declare and use your array inside onDataChange() method like this:

ref.child(key).addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        String[] value = {""}; //declaration of the array
        String str = dataSnapshot.getValue(String.class);
        System.out.println(str);
        value[0] = str;
        passingValue(value[0]);
    }

    @Override
    public void onCancelled(DatabaseError databaseError) {
        System.out.println("The read failed: " + databaseError.getCode());
    }
});

Please see the declaration of the array inside onDataChange() method. For a more complex answer, please see my answer from this post, which also contains a reference on how to use that value outside onDataChange() method

Alex Mamo
  • 130,605
  • 17
  • 163
  • 193