THe_strOX
THe_strOX

Reputation: 717

How to get the key from the value in firebase

How do I get the key "-KLpcURDV68BcbAvlPFy" when I know the field "name" contains "efg" in the following structure in Firebase.

clubs
    -KLpcURDV68BcbAvlPFy
        dept: "abc"
        desc: "xyz"
        name: "efg"
    -asdasdasddsad
        dept: "asda"
        desc: "asd"
        name: "adddd"

I tried this but it returned "clubs"

mDatabase.child("clubs").orderByChild("name").equalTo("efg").addListenerForSingleValueEvent(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            String clubkey =dataSnapshot.getKey();

Upvotes: 15

Views: 64235

Answers (8)

Kevin
Kevin

Reputation: 179

Solution in Java (100% working!):

//firebase reference
DatabaseReference  mRef = FirebaseDatabase.getInstance().getReference();

//set THe_strOX's database contents from the question
mRef.child("clubs").child("-KLpcURDV68BcbAvlPFy").child("dept").setValue("abc");
mRef.child("clubs").child("-KLpcURDV68BcbAvlPFy").child("desc").setValue("xyz");
mRef.child("clubs").child("-KLpcURDV68BcbAvlPFy").child("name").setValue("efg");
mRef.child("clubs").child("-asdasdasddsad").child("dept").setValue("asda");
mRef.child("clubs").child("-asdasdasddsad").child("desc").setValue("asd");
mRef.child("clubs").child("-asdasdasddsad").child("name").setValue("adddd");
//

mRef.child("clubs").addChildEventListener(new ChildEventListener() {
    @Override
    public void onChildAdded(@NonNull DataSnapshot dataSnapshot, String s)
    {
        if (dataSnapshot.exists())
        {
            String pushkey = dataSnapshot.getKey();
            mRef.child("clubs").child(pushkey).addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(@NonNull DataSnapshot dataSnapshot, String s)
                {
                    if (dataSnapshot.exists())
                    {
                        if (dataSnapshot.getKey().toString().equals("name")) {
                            //edit efg to any desired value
                            if (dataSnapshot.getValue().toString().equals("efg")) {
                                Toast.makeText(MainActivity.this, pushkey, Toast.LENGTH_SHORT).show();
                            }
                        }
                    }
                }
                @Override
                public void onChildChanged(@NonNull DataSnapshot dataSnapshot, String s) { }
                @Override
                public void onChildRemoved(@NonNull DataSnapshot snapshot) { }
                @Override
                public void onChildMoved(@NonNull DataSnapshot snapshot, @androidx.annotation.Nullable String previousChildName) { }
                @Override
                public void onCancelled(@NonNull DatabaseError error) { }
            });
        }
    }
    @Override
    public void onChildChanged(@NonNull DataSnapshot dataSnapshot, String s) { }
    @Override
    public void onChildRemoved(@NonNull DataSnapshot snapshot) { }
    @Override
    public void onChildMoved(@NonNull DataSnapshot snapshot, @androidx.annotation.Nullable String previousChildName) { }
    @Override
    public void onCancelled(@NonNull DatabaseError error) { }
});

}

Upvotes: 0

BegYourPardon
BegYourPardon

Reputation: 197

Here is how I did it in Kotlin

var ref  = database.child("clubs")
val database_listener = object : ValueEventListener {
        override fun onDataChange(dataSnapshot: DataSnapshot) {
            for (ds in dataSnapshot.children) {
                val key = ds.key
           }
        }
     }
   ref.addValueEventListener(database_listener)

Upvotes: 0

PhilCowan
PhilCowan

Reputation: 533

I've figured out a very easy way to do this. You need to get the auto-generated key before you send it to firebase. So for my project I did something like the following:

var database = firebase.database();
var rootRef = database.ref();
var autoId = rootRef.push().key
rootRef.child(autoId).set({
key: value,
key: value,
key: value,
autoid: autoId
})

Now when i go to my child added function and take a snapshot, I can easily get to snapshot.val().autoid and store it in a variable or as a button attribute so that I can delete it later.

Upvotes: 2

Sajjad Javed
Sajjad Javed

Reputation: 149

We can use HashMap.

initialize:

String for storing Key value. ModelClass for storing you data.

val hashMap: HashMap<String, "Your Model Class"> = hashMapOf()
databaseReference.child("/Product").orderByChild("ProductName")
        .addValueEventListener(object : ValueEventListener {
            override fun onCancelled(p0: DatabaseError) {

            }

            override fun onDataChange(p0: DataSnapshot) {
                /*p0.children.mapNotNullTo(models) { it.getValue(ProductModel::class.java) }.run {

                }*/
                p0.children.forEach {
                    val value = it.getValue(ProductModel::class.java) as ProductModel
                    hashMap[it.key!!] = value
                }.run { adp.update(hashMap) }
            }
        })

after this we can also get key & its value by using (index)

5 is Index

hashMap.keys.elementAt(5)
hashMap.values.elementAt(5)

Upvotes: 0

Malik Ali
Malik Ali

Reputation: 175

firebaseDatabase = FirebaseDatabase.getInstance();
mReference = firebaseDatabase.getReference("clubs");

mReference.addValueEventListener(new ValueEventListener() {
    @Override
    public void onDataChange(@NonNull DataSnapshot dataSnapshot) {
        for (DataSnapshot ds: dataSnapshot.getChildren()){
            String key = ds.getKey();
        }
    }
}

Upvotes: 3

Rob
Rob

Reputation: 2333

If anyone needs to do this using Kotlin:

mDatabase.child("clubs")
        .orderByChild("name")
        .equalTo("efg")
        .addListenerForSingleValueEvent(object: ValueEventListener {

            override fun onDataChange(dataSnapshot: DataSnapshot) {

                dataSnapshot.children.forEach {
                     //"it" is the snapshot
                     val key: String = it.key.toString()
                }
            }

            override fun onCancelled(p0: DatabaseError) {
                    //do whatever you need
            }
         })

Upvotes: 6

Chirag Gupta
Chirag Gupta

Reputation: 485

If this key (asdasdasddsad) also had the name:"efg" will club key will become asdasdasddsad and KLpcURDV68BcbAvlPFy

Upvotes: 0

Frank van Puffelen
Frank van Puffelen

Reputation: 599956

That's because you're using a ValueEventListener. If the query matches multiple children, it returns a list of all those children. Even if there's only a single matches child, it's still a list of one. And since you're calling getKey() on that list, you get the key of the location where you ran the query.

To get the key of the matches children, loop over the children of the snapshot:

mDatabase.child("clubs")
         .orderByChild("name")
         .equalTo("efg")
         .addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        for (DataSnapshot childSnapshot: dataSnapshot.getChildren()) {
            String clubkey = childSnapshot.getKey();

But note that if you assume that the club name is unique, you might as well store the clubs under their name and access the correct one without a query:

mDatabase.child("clubs")
         .child("efg")
         .addListenerForSingleValueEvent(new ValueEventListener() {
    @Override
    public void onDataChange(DataSnapshot dataSnapshot) {
        String clubkey = dataSnapshot.getKey(); // will be efg

Upvotes: 23

Related Questions