Firebase Angular 2-防止为每个订阅的客户端刷新观察到的对话列表的方法
所以我利用Angular 2/Firebase observables创建一个用户参与的对话列表。但是,我注意到,如果在Firebase Angular 2-防止为每个订阅的客户端刷新观察到的对话列表的方法,angular,firebase,firebase-realtime-database,ionic2,Angular,Firebase,Firebase Realtime Database,Ionic2,所以我利用Angular 2/Firebase observables创建一个用户参与的对话列表。但是,我注意到,如果在/conversations端点中更新了任何对话,即使用户不是该对话的一部分,其对话列表的UI也会显示刷新 基本上,我试图弄清楚这是因为所有的对话都在一棵树中,还是我的代码中有什么东西导致了这种情况的发生 无论哪种方式,下面是一个如何设计我的对话树的示例: /conversations { "-KfOStwLKzERlOxIaU7V" : { "created_at
/conversations
端点中更新了任何对话,即使用户不是该对话的一部分,其对话列表的UI也会显示刷新
基本上,我试图弄清楚这是因为所有的对话都在一棵树中,还是我的代码中有什么东西导致了这种情况的发生
无论哪种方式,下面是一个如何设计我的对话树的示例:
/conversations
{
"-KfOStwLKzERlOxIaU7V" : {
"created_at" : "2017-03-16T23:32:59.830Z",
"creator_id" : "dsfsdg12123RSDvsfbgrgwef",
"last_message" : "helllooo",
"last_message_author_id" : "dsfsdg12123RSDvsfbgrgwef",
"last_updated" : "2017-03-16T23:46:05.645Z",
"type" : "individual",
"users" : {
"dsfsdg12123RSDvsfbgrgwef" : true,
"gHRdadg567AAA344cGHJsaw1" : true
}
}
}
{
"convoId1": true,
"convoId2": true
}
/users/{userID}/conversations
{
"-KfOStwLKzERlOxIaU7V" : {
"created_at" : "2017-03-16T23:32:59.830Z",
"creator_id" : "dsfsdg12123RSDvsfbgrgwef",
"last_message" : "helllooo",
"last_message_author_id" : "dsfsdg12123RSDvsfbgrgwef",
"last_updated" : "2017-03-16T23:46:05.645Z",
"type" : "individual",
"users" : {
"dsfsdg12123RSDvsfbgrgwef" : true,
"gHRdadg567AAA344cGHJsaw1" : true
}
}
}
{
"convoId1": true,
"convoId2": true
}
下面是获取特定用户对话的代码
getConvosForUser(userId) {
return this._af.database
.object(`/social/users/${userId}/conversations`)
// Switch to the joined observable
.switchMap((conversations) => {
// Delete the properties that will throw errors when requesting
// the convo keys
delete conversations['$key'];
delete conversations['$exists'];
delete conversations['$value'];
// Get an array of keys from the object returned from Firebase
let convoKeys = Object.keys(conversations);
let convosObj = conversations;
if(convoKeys.length > 0) {
return Observable.combineLatest(
convoKeys.map((convoKey) => this._af.database
.object(`/social/conversations/${convoKey}`)
),
(...conversations) => {
// Determine if the user is connected to the owner
convoKeys.forEach(key => {
conversations.forEach(conversation => {
if(conversation.$key === key) {
conversation['is_connected_to_owner'] = convosObj[key];
}
})
})
// Then return the aggregated conversation data
return conversations;
}
);
// Otherwise, just return an empty observable
} else {
return Observable.of([]);
}
});
}
getUsersForConversations(conversations) {
if(conversations.length > 0) {
// Since there are conversations, let's iterate
// over them and determine which to show.
conversations.forEach((conversation, index) => {
// Get user out of local storage
this.storage.get('user').then(user => {
let userKeys = [];
// Get the user IDs associated with this conversation
if(conversation.users) {
userKeys = Object.keys(conversation.users).filter(key => {
return key !== user.id;
});
}
let usersArr = [];
let obsUsers = Observable
.from(userKeys)
.flatMap(key => {
return Observable.combineLatest(
Observable.of(key),
this._af.database.object(`/social/conversations_last_deleted/${conversation.$key}/${user.id}`)
.filter((lastDeleted) => {
let convoLastUpdated = +(new Date(conversation.last_updated));
if((lastDeleted && lastDeleted.$value === null) ||
(lastDeleted && lastDeleted.last_deleted && (convoLastUpdated >= lastDeleted.last_deleted))) {
return true;
}
})
.flatMap(lastDeleted => {
return this._messages.getMessagesForConvo(conversation.$key, lastDeleted)
}),
(key, messages) => {
if (messages.length === 0) {
return null;
}
return key;
})
})
.flatMap(userKey => this._af.database.object(`/social/users/${userKey}`))
.subscribe((users) => {
// There is a weird bug with results returning null,
// so just check to make sure results aren't null and push
// the user result if it isn't
if(users.$value !== null) {
usersArr.push(users);
conversations[index].users = usersArr;
this.conversations = conversations;
}
});
});
});
} else {
return Observable.of([]);
}
}
最后是将二者结合在一起的代码:
// Get all of the conversations for a user
this.convosSub = this._messages.getConvosForUser(user.id).subscribe(conversations => {
this.usersConvosSub = this.getUsersForConversations(conversations);
});
我意识到这是很多代码,但我发誓…我的应用程序中的对话部分很容易是最复杂的部分,我已经和它斗争了好几个星期了。我的对话中有很多奇怪的行为,所以我不确定是我的树是如何构造的,还是我的代码是疯狂的
无论如何,我非常感谢您的帮助 目前还没有(高效且简单的)基于AngularFire2的解决方案。这就是我想要重构
FirebaseListObservable
的原因之一。看到了吗?我现在有点困在这个问题上了吗?是的,在AngularFire2提供了一些工具来告诉你列表已经更改,而且哪些项目已经更改、添加或删除之前,你几乎被困在这个问题上了。