54

I have been looking for a way to get one child object's data in Android Firebase.

I have found things like Firebase retrieve child Android. All the solutions are suggesting using a "ChildEventListener", however I need to get this data at this moment, not when it is moved, deleted, updated, etcetera.

My data is kept in https://.firebaseio.com/users//creation as a string. I figure there must be some simple way to access that without needing to do too much, because if I copy the exact URL to my browser, I can see the: 'creation: "2015/05/31 21:33:55"' right there in my "Firebase Forge Dashboard".

How can I access this without a listener?

TylerH
  • 20,799
  • 66
  • 75
  • 101
Bobby
  • 1,416
  • 1
  • 17
  • 30

4 Answers4

65

Firebase listeners fire for both the initial data and any changes.

If you're looking to synchronize the data in a collection, use ChildEventListener. If you're looking to synchronize a single object, use ValueEventListener. Note that in both cases you're not "getting" the data. You're synchronizing it, which means that the callback may be invoked multiple times: for the initial data and whenever the data gets updated.

This is covered in Firebase's quickstart guide for Android. The relevant code and quote:

FirebaseRef.child("message").addValueEventListener(new ValueEventListener() {
  @Override
  public void onDataChange(DataSnapshot snapshot) {
    System.out.println(snapshot.getValue());  //prints "Do you have data? You'll love Firebase."
  }
  @Override
  public void onCancelled(DatabaseError databaseError) {        
  }
});

In the example above, the value event will fire once for the initial state of the data, and then again every time the value of that data changes.

Please spend a few moments to go through that quick start. It shouldn't take more than 15 minutes and it will save you from a lot of head scratching and questions. The Firebase Android Guide is probably a good next destination, for this question specifically: https://firebase.google.com/docs/database/android/read-and-write

darknite
  • 48
  • 7
Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
  • 1
    Thanks! You were a great help! – Bobby Jun 01 '15 at 02:42
  • 1
    note `getValue` has another overload for parsing objects. e.g. `User user = snapshot.getValue(User.class);` – Jossef Harush Kadouri May 26 '18 at 20:08
  • its will show DataSnapshot{key="", value=""} so we will define here snapshot.getValue(User.class); – Pradeep Sheoran Sep 02 '18 at 10:25
  • 2
    There is a bug in Android Firebase SDK that forces you to listen to all child events such as childAdded, childDeleted, childChanged, and childMoved. In iOS and Web Firebase SDK, you can listen to specific child event like child added only. Forced to listen all events means there will be most cost in your bill in terms of data downloaded. Hopefully Android team fixes this limitation and be consistent with other platforms. – coolcool1994 May 13 '20 at 18:23
  • All SDKs download all data for a location you listen to. There is no difference in the wire traffic between listening for just `child_added`, listening for all `child_` events, or listening for `value`. Btw: I have no idea what this comment has to do with this question, nor why you downvoted my answer. – Frank van Puffelen May 13 '20 at 18:45
26

You don't directly read a value. You can set it with .setValue(), but there is no .getValue() on the reference object.

You have to use a listener. If you just want to read the value once, you use ref.addListenerForSingleValueEvent().

Example:

Firebase ref = new Firebase("YOUR-URL-HERE/PATH/TO/YOUR/STUFF");
ref.addListenerForSingleValueEvent(new ValueEventListener() {
   @Override
   public void onDataChange(DataSnapshot dataSnapshot) {
       String value = (String) dataSnapshot.getValue();

       // do your stuff here with value

   }

   @Override
   public void onCancelled(FirebaseError firebaseError) {

   }
});

Source: https://www.firebase.com/docs/android/guide/retrieving-data.html#section-reading-once

lenooh
  • 10,364
  • 5
  • 58
  • 49
  • 3
    This is the response that more specifically answers the question in that there is no simple one line of code way to retrieve a bit of data in your firebase database just once, like '.getValue()'. It then tells how you have to do it, '.addListenerForSingleValueEvent', with a reference. Note 'FirebaseError' has been depreciated to the more generic 'DatabaseError'. – Androidcoder Dec 28 '16 at 16:02
13

just fetch specific node data and its working perfect for me

mFirebaseInstance.getReference("yourNodeName").getRef().addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {


        for (DataSnapshot postSnapshot : dataSnapshot.getChildren()) {
            Log.e(TAG, "======="+postSnapshot.child("email").getValue());
            Log.e(TAG, "======="+postSnapshot.child("name").getValue());
        }
    }

    @Override
    public void onCancelled(DatabaseError error) {
        // Failed to read value
        Log.e(TAG, "Failed to read app title value.", error.toException());
    }
});
tej shah
  • 2,995
  • 2
  • 25
  • 35
  • can i only directly use datasnapshot,child("email").getValue() ? , i mean without using datasnapshot.getChildren() – Goofy_Phie May 27 '17 at 02:14
  • its repeats a loop when something change in database manually. when i changed few value in database the it show multi times the same value – Pradeep Sheoran Sep 02 '18 at 10:58
  • its showing null pointer exception if i put : txtmsg.append(postSnapshot.child("name").getValue()); what is the solution for this. I put this code for many types but every explanation of code shows null exception – Pradeep Sheoran Sep 02 '18 at 11:21
12

I store my data this way:

accountsTable ->
  key1 -> account1
  key2 -> account2

in order to get object data:

accountsDb = mDatabase.child("accountsTable");

accountsDb.child("some   key").addListenerForSingleValueEvent(new ValueEventListener() {
                @Override
                public void onDataChange(DataSnapshot snapshot) {

                    try{

                        Account account  = snapshot.getChildren().iterator().next()
                                  .getValue(Account.class);


                    } catch (Throwable e) {
                        MyLogger.error(this, "onCreate eror", e);
                    }
                }
                @Override public void onCancelled(DatabaseError error) { }
            });
bat-el.g
  • 309
  • 4
  • 6