我想合并两个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)获取图像。它可以工作,但是当我将两个集合合并到一个数组中时,我希望有一个更好的解决方案。我不仅必须将它们组合起来,而且还必须在评论对象中包含作为对象的答复。
答案 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
}