39

I'm able to query my users array with an e-mail address and return the user's account info:

users.orderByChild('email').equalTo(authData.user.email).once('value').then(function(snapshot) {
        console.log(snapshot.val());
        console.log(snapshot.key); // 'users'
        console.log(snapshot.child('email').key); 'email'
        ...

enter image description here

How do I get the key (-KiBBDaj4fBDRmSS3j0r). snapshot.key returns users. snapshot.child('email').key returns email. The key doesn't appear to be a child, i.e., it appears to be in between users and email.

AL.
  • 36,815
  • 10
  • 142
  • 281
Thomas David Kehoe
  • 10,040
  • 14
  • 61
  • 100

5 Answers5

50

You could do something like this:

var key = Object.keys(snapshot.val())[0];

Ref: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

The Object.keys() method returns an array of a given object's own enumerable properties, in the same order as that provided by a for...in loop (the difference being that a for-in loop enumerates properties in the prototype chain as well).

camden_kid
  • 12,591
  • 11
  • 52
  • 88
31

Realtime database:

For this you can simple use: snapshot.key

snapshot = firebase.database.DataSnapshot

this.app.database()
        .ref('/data/')
        .on('value', function(snapshot) {
            const id = snapshot.key;

            //----------OR----------//
            const data = snapshot.val() || null;
            if (data) {
              const id = Object.keys(data)[0];
            }
        });

Firestore:

snapshot.id

snapshot = firebase.firestore.DocumentSnapshot

this.app.firestore()
        .collection('collection')
        .doc('document')
        .onSnapshot(function(snapshot) {
            const id = snapshot.id;

            //----------OR----------//
            const data = snapshot.data() || null;
            if (data) {
              const id = Object.keys(data)[0];
            }
        });
Ernestyno
  • 797
  • 1
  • 10
  • 16
6

users.orderByChild('email').equalTo(authData.user.email) is a Query (doc) that you have built by "chaining together one or more of the filter methods". What is a bit specific with your query is that it returns a dataSnapshot with only one child, since you query with equalTo(authData.user.email).

As explained here, in this exact case, you should loop over the returned dataSnapshot with forEach():

Attaching a value observer to a list of data will return the entire list of data as a single snapshot which you can then loop over to access individual children.

Even when there is only a single match for the query, the snapshot is still a list; it just contains a single item. To access the item, you need to loop over the result, as follows:

ref.once('value', function(snapshot) {
  snapshot.forEach(function(childSnapshot) {
    var childKey = childSnapshot.key;
    var childData = childSnapshot.val();
    // ...
  });
});
Renaud Tarnec
  • 79,263
  • 10
  • 95
  • 121
5

Similar to camden_kid, I used Object.keys(arr), but in three lines:

var arr = snapshot.val();
var arr2 = Object.keys(arr);
var key = arr2[0];
console.log(key) // -KiBBDaj4fBDRmSS3j0r
Thomas David Kehoe
  • 10,040
  • 14
  • 61
  • 100
3

I found new way to get the data based on snapshot key -

 firebase.database().ref('events').once('value',(data)=>{
      //console.log(data.toJSON());
      data.forEach(function(snapshot){
        var newPost = snapshot.val();
        console.log("description: " + newPost.description);
        console.log("interest: " + newPost.interest);
        console.log("players: " + newPost.players);
        console.log("uid: " + newPost.uid);
        console.log("when: " + newPost.when);
        console.log("where: " + newPost.where);
      })
      })
  • I had the almost the same issue as the OP and ended doing this and other kinds of foreach/for and indeed the get the info but due to the scope I lost the values. Do you have a recommendation on that? It would be very helpful. – Marco Santana Nov 13 '19 at 02:31