使用AngularFire2从Firebase中的多个键中检索值

时间:2017-07-04 06:11:06

标签: angular typescript firebase angularfire2

我刚开始使用angularFire2。我有一些Firebase数据结构如下:

{
    "user-friends": {
        "-userkey1": {
            "-userkey2": true,
            "-userkey3": true
        }
    },

    "users": {
        "-userkey1": {
            "uid": "id1",
            "uname": "Jim Yu"
        },
        "-userkey2": {
            "uid": "id2",
            "uname": "Bob Smith"
        },
        "-userkey3": {
            "uid": "id3",
            "uname": "Jane Doe"
        }
    }
}

到目前为止,我可以在user-friends节点中检索-userkey1的数据,返回

   "-userkey1": {
        "-userkey2": true,
        "-userkey3": true
    }

然后我希望能够获取每个密钥的uname,并将其存储在将绑定到视图的变量中。

我有点不确定如何使用angularFire2来完成最后一步。如果有一个角度/ firebase特定方法/辅助方法来解决这个问题。

到目前为止,这就是我所拥有的,但是一旦我遍历每个密钥并尝试将用户名推送到数组中,控制台就会记录第一个密钥uname,然后尖叫cannot read property 'push' of undefined

userFriends(userkey: string){
    console.log("userKey=" + userkey)
    var getUsrFriends = this.afDB.list("https://myfirebaseurl.com/user-friends/" + userkey
    ).subscribe( data => {
        data.forEach(friendKey => {
            console.log(friendKey.$key) //my instinct tells me looping through the keys and storing in an array is not a optimal solution
            var getUserInfo = this.afDB.object("https:/myfirebaseurl.com/users/" + friendKey.$key, {
            }).subscribe( u => {
                console.log(u.uname)
                this.friendsList.push(u.uname) // <- undefined error 
            })    
        });       
    })   
}

<ng-container  *ngIf="showView == 'friend'">
    <ion-list *ngFor="let friend of friendsList">
        <h3>{{friend}}</h3>
    </ion-list>
</ng-container>

编辑:未定义的错误实际上是由于没有正确初始化friendsList数组引起的。

export class UserPage {
  friendsList: string[] = []
 // constructor, etc
}

1 个答案:

答案 0 :(得分:1)

Firebase非常快,所以进行多次通话也不错。

使用您当前的数据结构,此代码将起作用:

// Outside firebase calls
let scope = this;

...
var getUserInfo = this.afDB.object("https:/myfirebaseurl.com/users/" + friendKey.$key, {}).take(1).subscribe( u => {
    console.log(u.uname)
    scope.friendsList.push(u.uname) // <- undefined error 
})
...

this,一旦进入Firebase承诺,就会被该承诺保留,并且意味着与常规保留的this全局组件变量不同。

此外,在订阅之前使用take(1),因为您只想检索一次这些值而不是继续收听。

另一种方法是重构数据库,以便在权衡中进行更快速的查询以获得更多数据存储。您可以存储整个user-friends,而不是仅存储user内的用户参考。但我会建议第一种选择。