Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/neo4j/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Json 使用angularfire2查询Firebase实时数据库中的数据关系_Json_Angular_Firebase Realtime Database_Rxjs_Angularfire2 - Fatal编程技术网

Json 使用angularfire2查询Firebase实时数据库中的数据关系

Json 使用angularfire2查询Firebase实时数据库中的数据关系,json,angular,firebase-realtime-database,rxjs,angularfire2,Json,Angular,Firebase Realtime Database,Rxjs,Angularfire2,我需要查询评论并只请求在评论中按userId列出的用户 Firebase实时数据库中的我的数据库结构: { "comments" : { "c_id1" : { "commentId" : "c_id1", "commentText" : "text", "userId" : "u_id1" }, "c_id2" : { "commentId" : "c_id2", "commentText" : "text

我需要查询评论并只请求在评论中按userId列出的用户

Firebase实时数据库中的我的数据库结构:

{
  "comments" : {
    "c_id1" : {
      "commentId" : "c_id1",
      "commentText" : "text",
      "userId" : "u_id1"
    },
    "c_id2" : {
      "commentId" : "c_id2",
      "commentText" : "text",
      "userId" : "u_id3"
    },
  },

  "users" : {
    "u_id1" : {
      "userId" : "u_id1",
      "userName" : "name1",
    },
    "u_id1" : {
      "userId" : "u_id2",
      "userName" : "name2",
    },
    "u_id1" : {
      "userId" : "u_id3",
      "userName" : "name3",
    }
  }
}
最后我需要的是注释[],其中注释是:

{
  "commentId" : "c_id",
  "commentText" :"text",
  "userId" : "u_id",
  "user" : {
    "userId":"u_id",
    "userName":"name"
  }
}
所以,要评论的类是

export class Comment {
  commentId: string;
  commentText: string;
  userId: string;
  user?: User;
}
到目前为止,我设法获得了所有用户,然后将他们映射到客户端的评论。但如果db有N个用户,只有2条评论,其中N>>2条,情况会不会太糟呢

  OnGetUsersForComments(){
    return this.angularFireDatabase.list("/comments").valueChanges()
      .subscribe((data) => {
        this.commentsUsers = data;
        this.OnGetCommentsForTask()
      });
  }

  OnGetCommentsForTask(){
    this.angularFireDatabase.list("/comments").valueChanges()
      .map((comments) => {
        return comments.map( (comment: TaskComment) => {
          this.commentsUsers.forEach((user: User) => {
            if (comment.userId === user.userId) {
              comment.commentUser = user;
            }
          });
          return comment;
        });
      })
      .subscribe((data)=> {
        this.comments = data;
      });
  }
有没有办法只从评论中获取用户

我还尝试将其添加到用户中,但没有成功:

"userComments" : {
  "uc_id1" : {
    "commentId" : c_id2
  },
}

更新0

我已经编辑了这个问题,我希望现在更清楚

我已经能够让它像这样工作: 来自- 及

但是我想把它转换成可观察的,因为如果不刷新页面,我就看不到评论是否被删除了


更新1

在CommentBellow的帮助下,我完成了这个实现

onGetComments(){
  this.angularFireDatabase.list("/comments").valueChanges()
    .mergeMap((comments) => {
      return comments.map((comment)=>{
        this.firebaseService
          .onListData('/users', ref => ref.orderByChild('userId').equalTo(comment.userId))
          .valueChanges()
          .subscribe((user: User[])=> {
            comment.user = user[0];
          })
        return comment;
      })
    })
    .subscribe((comment)=> {
      console.log(comment);
    });
}

这将返回单独的注释,我希望在其中接收注释[],我将尝试使用子事件:“添加了child_”、“更改了child_”、“删除了child_”和“移动了child_”,而使用snapshotChanges().valueChanges()。

好的,根据您的更新,我个人将首先创建两个助手界面:

interface User {
    userId: string;
    userName: string;
}

interface FullComment {
    commentId: string;
    userId: string;
    user: User;
}

interface CommentObject {
    commentId: string;
    commentText: string;
    userId: string;
}
然后是超级方便的助手方法:

getUser(uid: string): Observable<User> {
    return this.db.object<User>(`/users/${uid}`)
    .valueChanges()
}

getFullComment(commentObject: CommentObject): Observable<FullComment> {
    return this.getUser(commentObject.userId)
    .map((user: User) => {
        return {
            commentId: commentObject.commentId,
            commentText: commentObject.commentText,
            user: user,
        };
    });
}
getUser(uid:string):可观察{
返回此.db.object(`/users/${uid}`)
.valueChanges()
}
getFullComment(commentObject:commentObject):可观察{
返回此.getUser(commentObject.userId)
.map((用户:用户)=>{
返回{
commentId:commentObject.commentId,
commentText:commentObject.commentText,
用户:用户,,
};
});
}
最后看看让FullComment对象可见变得多么容易:

getComments(): Observable<FullComment[]> {
    return this.db
    .list(`/comments`)
    .valueChanges()
    .switchMap((commentObjects: CommentObject[]) => {
        // The combineLatest will convert it into one Observable
        // that emits an array like: [ [fullComment1], [fullComment2] ]
        return Observable.combineLatest(commentObjects.map(this.getFullComment));
    });
}
getComments():可观察{
返回这个.db
.list(`/comments`)
.valueChanges()
.switchMap((commentObjects:CommentObject[])=>{
//CombineTest将把它转换成一个可观察的
//它会发出如下数组:[[fullComment1],[fullComment2]]
返回Observable.combineLatest(commentObjects.map(this.getFullComment));
});
}
我想这就是你需要的。请让我知道这是否有帮助。 使用可观测数据进行愉快编码;)


最新更新:以前忘记进行最后一次转换以修复TypeError,所以现在必须正常。

Hi。谢谢你的回复,我给了我一些新的信息来搜索和研究。但这并不是我想要的。我已经更新了问题,希望现在更清楚。我曾尝试使用.switchMap和.mergeMap实现我需要的功能,但在订阅时,我得到了单独的“Comment”对象,所以当它被新添加或删除时,它会变得疯狂。希望我能尽快搞定。你真是个天才。谢谢但我不太确定.map(Array.prototype.concat)的用途,因为在我的例子中,它只是添加了MapSubscriber{closed:false,…}对象和最后的空0元素。在4条评论的情况下,我得到了6个元素的数组。那么,它现在在你的应用程序中是否按照你预期的方式工作?好的,我刚刚意识到没有必要在最后的数组中使用concat。我的错对不起
getComments(): Observable<FullComment[]> {
    return this.db
    .list(`/comments`)
    .valueChanges()
    .switchMap((commentObjects: CommentObject[]) => {
        // The combineLatest will convert it into one Observable
        // that emits an array like: [ [fullComment1], [fullComment2] ]
        return Observable.combineLatest(commentObjects.map(this.getFullComment));
    });
}