Vik
Vik

Reputation: 9289

firebase realtime DB getting key of matched object

My firebase realtime DB is structured like:

{
 "users" : {
    "P55dsK5xQaM3FhnsCcI5Oxnyi7v1" : {
      "email" : "[email protected]",
      "isAdmin" : true,
      "name" : "Vik Kumar"
    }
  }
}

I am using angularfire2 to query data like below

getUserByEmail(email:string){
    console.log("start of getUserByEmail with email:" + email)
    return new Promise((resolve, reject) =>
      {

        this.db.list("/users", 
          ref => ref.orderByChild('email').startAt(email)
        ).valueChanges().subscribe(
          res => {
            console.log('response:' + JSON.stringify(res))
            resolve(res)
          },
          err => {
            console.log(err)
            reject(err)
          }
        )
      })
  }

This works as expected. However, i need the id of this node "P55dsK5xQaM3FhnsCcI5Oxnyi7v1" as well to do some operations. How do i get that?

My Business Use Case The users get added to note users node as they sign up. The above requirement came where an admin user want to update user data. So, he searches the user via his email and then update it.

So the above code is used to search users by email. Now, to be able to update i need to get the node id.

Upvotes: 1

Views: 123

Answers (3)

Vik
Vik

Reputation: 9289

So, actually i could do it using angularfire2 by replacing valueChanges to snapshotchanges as below

 getUserByEmail(email:string){
    console.log("start of getUserByEmail with email:" + email)
    return new Promise((resolve, reject) =>
      { 
        this.db.list("/users", 
          ref => ref.orderByChild('email').startAt(email)
        ).snapshotChanges().subscribe(
          (res:any) => {
            console.log("resp length:" + res.length)
            //console.log('response:' + JSON.stringify(res))
            //console.log('key is::' + res.key())
            resolve(res)
          },
          err => {
            console.log(err)
            reject(err)
          }
        )
      })
  }

now res.key gives me key and res.payload.val() the data object.

Upvotes: 0

Frank van Puffelen
Frank van Puffelen

Reputation: 598847

I'm not sure why you're using AngularFire here. With the regular Firebase SDK for JavaScript, you can do this with:

getUserByEmail(email:string){
  console.log("start of getUserByEmail with email:" + email)
  return new Promise((resolve, reject) =>{
    firebase.database()
      .ref("/users")
      .orderByChild('email')
      .startAt(email)
      .once('child_added')
      .then(snapshot => {
        resolve(snapshot.key);
      })
      .catch(err => {
        console.log(err)
        reject(err)
      })
  });
}

By listening for once('child_added' we're getting a snapshot that only contains the first child node matching the query.


Note that the search now will match any user after the email, while I have a feeling you want to only find users starting with the value of email. In that case you'll want to add an endAt() clause too:

firebase.database()
  .ref("/users")
  .orderByChild('email')
  .startAt(email)
  .endAt(email+'\uF7FF')
  .once('child_added')

Upvotes: 1

youDaily
youDaily

Reputation: 1384

You can try like that

this.itemsRef = db.list('users');
this.itemsRef.snapshotChanges(['child_added'])
  .subscribe(actions => {
    actions.forEach(action => {
      console.log(action.type);
      console.log(action.key);
      console.log(action.payload.val());
    });
  });

Upvotes: 0

Related Questions