简体   繁体   中英

Calling then function after fetching data from firebase in ionic 3

I want fetch data from firebase after that I want to execute another function. Second function have to wait until first one is complete .

this.oAngularFireDatabase.database.ref('Users').orderByKey()
            .on('value', snapshot => {
              if (snapshot.hasChildren()) {
                snapshot.forEach(innerSnap => {
                  if (innerSnap.hasChild(user.uid)) {
                    //User role key
                    this.loggedInUserUserRoleKey = innerSnap.key;
                    //User id
                    this.loggedInUserId = user.uid;

                    //User name
                    this.loggedInUserName = innerSnap.child(user.uid).child("user_name").val();

                    if (innerSnap.child(user.uid).hasChild("user_image")) {
                      //User Image
                      this.loggedInUserImage = innerSnap.child(user.uid).child("user_image").val();
                    }
                    return false;
                  }
                })
              }
            }) 

I can't call then function after on it gives me an error. In my above code, I want call another function after all data are fetch from firebase.

The Firebase on() method can fire multiple times: once when it initially loads the data, and again whenever the data changes. Since a promise (the thing you call then() on) can only resolve once, on() can't return a promise.

There are two options here:

  1. You want to only load the data once.

    If this is the case, you should use Firebase's once() method, which does return a promise.

     this.oAngularFireDatabase.database.ref('Users').orderByKey() .once('value').then(snapshot => { if (snapshot.hasChildren()) { snapshot.forEach(innerSnap => { if (innerSnap.hasChild(user.uid)) { //User role key this.loggedInUserUserRoleKey = innerSnap.key; //User id this.loggedInUserId = user.uid; //User name this.loggedInUserName = innerSnap.child(user.uid).child("user_name").val(); if (innerSnap.child(user.uid).hasChild("user_image")) { //User Image this.loggedInUserImage = innerSnap.child(user.uid).child("user_image").val(); } return false; } }) } }).then(value => { // TODO: perform subsequent action on boolean value }) 
  2. You want to listen for changes on the data too.

    If this is the case, you should put the subsequent action you want to take into the on() callback:

     this.oAngularFireDatabase.database.ref('Users').orderByKey() .on('value', snapshot => { if (snapshot.hasChildren()) { snapshot.forEach(innerSnap => { if (innerSnap.hasChild(user.uid)) { //User role key this.loggedInUserUserRoleKey = innerSnap.key; //User id this.loggedInUserId = user.uid; //User name this.loggedInUserName = innerSnap.child(user.uid).child("user_name").val(); if (innerSnap.child(user.uid).hasChild("user_image")) { //User Image this.loggedInUserImage = innerSnap.child(user.uid).child("user_image").val(); } } }) // TODO: perform subsequent action on data } }) 

Note that both of these operations look pretty expensive for what they're trying to accomplish: scanning a JSON tree for a specific value is an anti-pattern in Firebase, and typically means you should modify/augment your JSON to allow a direct lookup or query.

For example, I suspect you now have a structure like /Users/$randomkey/$uid: { ..user data... } . For better performance, consider storing the user data directly under their UID: /Users/$uid: { ..user data... } . This removes the need for a query, and allows you to directly load the data for a user from this.oAngularFireDatabase.database.ref('Users').child(user.uid) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM