44

In my app, I need to check if a given element of my database on firebase has a child with a given name. I hoped it could be done by using something along the lines of:

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();

if (rootRef.childExists("name")) {
    //run some code
}

I searched but I couldn't find anything useful.

CopsOnRoad
  • 237,138
  • 77
  • 654
  • 440
zomnombom
  • 986
  • 2
  • 9
  • 15

6 Answers6

86

Edit 2; worth putting on top: I think it is worth mentioning that this is actually downloading all data at this snapshot just to check whether any data exists. You should be mindful here. If the reference is huge (e.g. actually the root reference and not a specific child/property) then you should either find a deeper node you can use to check for existence or design your data structure differently so an efficient check is possible.

A database reference is effectively the URL for that data. You want to actually get data to see whether a child exists. This is why the method you seem to be looking for is on DataSnapshot.

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  void onDataChange(DataSnapshot snapshot) {
    if (snapshot.hasChild("name")) {
      // run some code
    }
  }
});

Now, this design pattern feels a bit strange. You're reading the whole database just to see whether "name" exists. You can make this a bit more efficient by listening to rootRef.child("name") and then just checking whether snapshot.exists().

If you're trying to do validation here, and not control flow, you should consider putting this code in your rules.json.

edit: I originally used the wrong function name (childExists instead of hasChild)

Thomas Bouldin
  • 3,707
  • 19
  • 21
  • Just to clarify: Is it possible to access data on firebase without a listener? – zomnombom May 24 '16 at 13:09
  • 2
    I assume you're asking because you don't want the callback to run over and over. The "single" in the above code means that this only fires once. – Thomas Bouldin May 24 '16 at 15:08
  • Yes. Thanks very much! – zomnombom May 25 '16 at 05:40
  • http://stackoverflow.com/questions/43752247/how-to-check-existed-data-in-firebase – chris May 03 '17 at 07:09
  • 2
    if DatabaseReference not exist onDataChange not called, because no any data, called method onCancelled() – Vahe Gharibyan Dec 16 '17 at 17:33
  • This will take all data under the database ref – Arsen Nersisyan Apr 18 '19 at 16:18
  • @ThomasBouldin I am using the same code i.e. if(dataSnapshot).hasChild("name") but it always returns false when it runs for the first time. If I run it again then it runs the expected value i.e. true. Any idea what I can do to fix this? – Ayush Malviya Jan 21 '20 at 08:02
  • @AyushMalviya this is because you have offline mode turned on. It checks first against your cache and then sets a listener against the node. You won’t get a second notification if the server matches the local cache so you have two options: make your app responsive to changes (what you generally intend when you have a listener) or bypass the cache by using a once query. – Thomas Bouldin Jan 31 '20 at 21:51
10

Don't do like this

NEVER

It will take all your data and bring to device

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  void onDataChange(DataSnapshot snapshot) {
    if (snapshot.hasChild("name")) {
      // run some code
    }
  }
});

Check it by this way. It will return the value of the child if exists, otherwise -> null

DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference();
rootRef.child("childName")
rootRef.addListenerForSingleValueEvent(new ValueEventListener() {
  @Override
  void onDataChange(DataSnapshot snapshot) {
    if (snapshot.getValue() == null) {
      // The child doesn't exist
    }
  }
});
Arsen Nersisyan
  • 458
  • 5
  • 18
6

A complete solution. No need to download all the data. Just check if the child exist like this:

// Assuming the names are in the name node. Remove "name/" if not
DatabaseReference rootRef = FirebaseDatabase.getInstance().getReference("name/" + name);
rootRef.addListenerForSingleValueEvent(new ValueEventListener() {

    @Override
    public void onDataChange(DataSnapshot snapshot) {
         if (snapshot.exists()) {
             // Exist! Do whatever.

         } else {
             // Don't exist! Do something.

         }
    }

    @Override
    public void onCancelled(DatabaseError error) {
        // Failed, how to handle?

    }

});
John T
  • 814
  • 10
  • 17
2

Try using .childexists in combination with .equalTo("Your specific name")

Rahul Shah
  • 1,387
  • 4
  • 22
  • 41
0
UsersRef = FirebaseDatabase.getInstance().getReference();   
Users.addListenerForSingleValueEvent(new ValueEventListener() {
                                @Override
                                public void onDataChange(DataSnapshot snapshot) {
                                    if (snapshot.hasChild("childName")) {

                                        // it exists!
                                    }else{
                                       // does not exist
                                    }
                                }

                                @Override
                                public void onCancelled(@NonNull DatabaseError databaseError) {

                                }
                            });
Arjun
  • 1,477
  • 1
  • 13
  • 23
0

Use snapshot.exists() to check if the referenced database entry contains a child , irrespective of the value of the child.