在Ionic 3中从Firebase获取数据后调用then函数

时间:2018-11-08 11:05:01

标签: javascript firebase ionic-framework firebase-realtime-database angularfire2

在执行其他功能之后,我想从Firebase提取数据。第二个功能必须等到第一个功能完成。

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;
                  }
                })
              }
            }) 

then之后我无法调用on函数,这给了我一个错误。 在我上面的代码中,我想在从firebase中获取所有数据后调用另一个函数。

1 个答案:

答案 0 :(得分:1)

Firebase on()方法可以触发多次:一次是在最初加载数据时,一次是在数据更改时。由于承诺(您调用then()的事物)只能解决一次,因此on()无法返回承诺。

这里有两个选项:

  1. 您只想加载一次数据。

    在这种情况下,您应该使用Firebase的once()方法,该方法返回承诺。

    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. 您也想听数据的变化。

    在这种情况下,应将要执行的后续操作放入on()回调中:

    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
          }
        }) 
    

请注意,这两种操作对于它们要完成的工作而言似乎都非常昂贵:在JSON树中扫描特定值是Firebase中的反模式,通常意味着您应该修改/增强JSON以允许使用直接查找或查询。

例如,我怀疑您现在具有类似/Users/$randomkey/$uid: { ..user data... }的结构。为了获得更好的性能,请考虑将用户数据直接存储在其UID下:/Users/$uid: { ..user data... }。这样就无需查询,并允许您直接从this.oAngularFireDatabase.database.ref('Users').child(user.uid)中为用户加载数据。