将两个Firebase集合合并到一个阵列中

时间:2020-10-29 22:35:03

标签: angular firebase collections

我想合并两个Firebase集合,但是我不确定该怎么做。 简而言之,我有一个包含所有评论和答复的评论集合,我需要通过电子邮件搜索从另一个集合中添加每个用户的图像。

我有以下型号:

export class UserAdditionalInfo {
  constructor (
    public name: string, 
    public phoneCode: number,
    public phone: number, 
    public email: string,
    public userImg: string,
    public id: string
  ){}
}

//...

import { CommentReply } from './comment-reply.model';
export class Comment {
  constructor(
    public name: string,
    public email: string,
    public date: firebase.firestore.Timestamp,
    public comment: string,
    public id: string,
    public replies?: CommentReply []
  ){}
}

//...

export class CommentReply {
  constructor(
    public name: string,
    public email: string,
    public date: firebase.firestore.Timestamp,
    public comment: string,
    public id: string,
    public commentId: string
  ){}
}

和收藏集:

  getComments() {
    return this.firestore
    .collection('comments', data => data.orderBy('date', 'asc'))
    .snapshotChanges();
  }
  
  //...
  
  getRegistration(email: string) {
    return this.firestore
    .collection('registrations', data => data.where('email', '==', email))
    .snapshotChanges();
  }

此刻,我从getComments()获得所有评论,然后通过电子邮件转换通过管道从getRegistration(email:string)获取图像。它可以工作,但是当我将两个集合合并到一个数组中时,我希望有一个更好的解决方案。我不仅必须将它们组合起来,而且还必须在评论对象中包含作为对象的答复。

1 个答案:

答案 0 :(得分:0)

Firestore的数据库非常严格,您不能在各种集合中执行INNER JOIN,这是因为Firesbase是一个NOSQL数据库,主要侧重于性能和安全性。因此,当您使用已经注册并存储在与当前用户相关的Web应用程序中的UserAdditionalInfo创建评论或评论回复时,建议插入图像URL。如果要进行更新/擦除,我建议使用与UserAdditionalInfo相关的更新/擦除触发器。

简而言之,复制沿着集合将需要的数据(在本例中为userImg),并创建触发器以保持集合的一致性。

看到您的评论,我给您写了一些代码:

在您的网络应用中

我开始编写存储UserAdditionalInfo的服务:


    export class UserService {
      private userAddtionalInfo: UserAdditionalInfo;
      ...
      login(userName: string, password: string){
        ...
        const userId = getUserId();
        if(userIsProperlyLogin){
          //Get user additional info from firestore
          userAdditionaInfo = getFromFirestoreUserAdditionalInfo(userId);
        }
      }
      getImageUrl(): string{
        return userAdditionInfo.userImg;
      }
    }

因此,当您发表评论或评论回复时:

//...
    export class CommentReply {
      constructor(
        public name: string,
        public email: string,
        public date: firebase.firestore.Timestamp,
        public comment: string,
        public id: string,
        public commentId: string,
        //Additional info
        userImageUrl: string
  ){}
}
//...
    export class Comment {
      constructor(
        public name: string,
        public email: string,
        public date: firebase.firestore.Timestamp,
        public comment: string,
        public id: string,
        public replies?: CommentReply [],
        //Additional info
        userImageUrl: string
      ){}
    }
//...
    export class CommentService {
      constructor(private userService: UserService){}
      ...
      private createComment(contain: string): Comment{
        ...
        comment.userImageUrl = userService.getImageUrl();
        return comment;
      }
      comment(contain:string){
        ...
        comment: Comment = createComment(contain);
        addCommentToFirestore(comment);
      }
      private createReply(contain: string): CommentReply{
        ...
        commentReply.userImageUrl = userService.getImageUrl();
      }
      reply(contain: string){
        reply: Reply = createReply(contain);
        addReplyToFirestore(reply);
      }
    }

关于CommentReply,我认为将数据移动到subcollection而不是数组中是允许与该答复相关的查询的好主意。

在云功能中:

我建议创建一个函数来在UserAdditionalInfo更改或删除时触发。 This is a good explanation about cloud functions in firebase。此外,此说明还提供了有关创建函数项目的分步指南。

关于更新UserAdditionInfo(使用Cloud Function中的Nodejs 10配置):

export const updateUserAdditionalInfoTrigger = functions.region('WRITE-HERE-YOUR-REGION').firestore
  .document(`UserAdditionInfo/{userAdditionalId}`)
  .onUpdate((change, context: functions.EventContext) => {
    //Check if email/imageUrl or any related data is changed
    //create a firestore transaction
    //Get all comments related with this user
    //Update all comments
    //Get all replies related with this user
    //Update all replies
    //End transaction
}