附加 FirebaseListObservable 并使用 endAt
Appending FirebaseListObservable and using endAt
我正在尝试 'lazy load' Angular 4 聊天应用程序中的消息,该应用程序使用 Firebase 作为其数据集。
这里的想法是在应用程序第一次加载时检索 x 条消息(现在数量为 3 以便于调试)并在用户滚动到顶部或按下 'more' 按钮时加载更多消息.
我写了一个加载消息的函数:
public retrieveMessages(conversationId, end?) {
const LIMIT_TO_LAST = 3;
if (this.firebaseUserIsAuthenticated()) {
if (end != null) {
console.log('retrieving next 10');
this.messages.subscribe(messages => {
const topMessage = messages[0].$key;
console.log('Top message: ' + topMessage);
const ref = this.firebaseApp.database().ref('messages/' + conversationId);
ref.orderByChild('id').endAt(topMessage).limitToLast(LIMIT_TO_LAST).on('child_added', function (snapshot) { // This gives us the top message + 'LIMIT_TO_LAST'-1 before it
console.log(snapshot.val());
messages.unshift(snapshot.val());
});
console.log(messages);
});
} else {
console.log('retrieving first 10');
this.messages = this.db.list('messages/' + conversationId, { query: { limitToLast: LIMIT_TO_LAST } });
}
this.messages.subscribe(messages => {
console.log('Retrieved messages for conversation with id ' + conversationId + '.');
});
}
}
Question 1: I need an 'endBefore' instead of 'endAt'
这里的第一个问题是 'endAt' 给我的记录包括具有 'endAt' 值的记录。:
初始消息数组=[消息13][消息14][消息15]
新消息数组=[消息11][消息12][消息13][消息13][消息14][消息15]
我当然可以 limitToLast(LIMIT_TO_LAST + 1) 并删除最后一个对象,但这很难看。这样做的正确方法是什么?
我想到了为每条消息添加一个时间戳键(具有毫秒值),按此时间戳键排序,然后说我们想要 "topMessage.timestamp - 1" 的所有消息。我还没有测试这是否可行(我不知道 endAt 键是否必须存在)但是当有 2 条消息具有完全相同的时间戳时这会产生问题,虽然这不太可能,但它仍然可能发生。
仅使用 limitToLast 在这里不是一个选项(第一次调用:limitToLast(3),第二次调用:limitToLast(6),依此类推),因为这并不意味着我们仅在检索时仅显示 3 条消息3.
假设我们检索到 3 条消息,但有人写了一条新消息,它也会显示(所以现在我们有 4 条消息)。如果用户随后按下 'loadMore',则只会加载 2 条新消息,而不是 3 条。
当我们加载 3 条消息,发送 4 条消息,然后检索“另外 3 条消息”时,这个问题会更糟。然后它将只删除第一个...
Question 2: Appending the list of messages:
this.messages 此时是一个 FirebaseListObservable<>。
据我所知,不可能将此列表附加到新检索到的消息中。
我正在考虑创建一个 this.messageObjects (或其他东西),其中包含一组消息对象。每次我检索更多消息时,我都可以附加该数组。
这是一个好主意吗?或者有更好的方法吗?
Additional info
我使用的是 firebase ID (-K3d--f3e2...),所以我不能简单地说 'endAt - 1' 或其他内容。
我现在使用 2 个对象而不是 1 个(1 个数组,包含消息,1 个包含该数组的主题(作为值,而不是作为参考))。
当我检索消息时,我将它们附加到数组并使用此数组(作为值,而不是通过引用)作为主题的参数调用 .next()。这样就可以了!
我正在尝试 'lazy load' Angular 4 聊天应用程序中的消息,该应用程序使用 Firebase 作为其数据集。
这里的想法是在应用程序第一次加载时检索 x 条消息(现在数量为 3 以便于调试)并在用户滚动到顶部或按下 'more' 按钮时加载更多消息. 我写了一个加载消息的函数:
public retrieveMessages(conversationId, end?) {
const LIMIT_TO_LAST = 3;
if (this.firebaseUserIsAuthenticated()) {
if (end != null) {
console.log('retrieving next 10');
this.messages.subscribe(messages => {
const topMessage = messages[0].$key;
console.log('Top message: ' + topMessage);
const ref = this.firebaseApp.database().ref('messages/' + conversationId);
ref.orderByChild('id').endAt(topMessage).limitToLast(LIMIT_TO_LAST).on('child_added', function (snapshot) { // This gives us the top message + 'LIMIT_TO_LAST'-1 before it
console.log(snapshot.val());
messages.unshift(snapshot.val());
});
console.log(messages);
});
} else {
console.log('retrieving first 10');
this.messages = this.db.list('messages/' + conversationId, { query: { limitToLast: LIMIT_TO_LAST } });
}
this.messages.subscribe(messages => {
console.log('Retrieved messages for conversation with id ' + conversationId + '.');
});
}
}
Question 1: I need an 'endBefore' instead of 'endAt'
这里的第一个问题是 'endAt' 给我的记录包括具有 'endAt' 值的记录。:
初始消息数组=[消息13][消息14][消息15]
新消息数组=[消息11][消息12][消息13][消息13][消息14][消息15]
我当然可以 limitToLast(LIMIT_TO_LAST + 1) 并删除最后一个对象,但这很难看。这样做的正确方法是什么? 我想到了为每条消息添加一个时间戳键(具有毫秒值),按此时间戳键排序,然后说我们想要 "topMessage.timestamp - 1" 的所有消息。我还没有测试这是否可行(我不知道 endAt 键是否必须存在)但是当有 2 条消息具有完全相同的时间戳时这会产生问题,虽然这不太可能,但它仍然可能发生。
仅使用 limitToLast 在这里不是一个选项(第一次调用:limitToLast(3),第二次调用:limitToLast(6),依此类推),因为这并不意味着我们仅在检索时仅显示 3 条消息3. 假设我们检索到 3 条消息,但有人写了一条新消息,它也会显示(所以现在我们有 4 条消息)。如果用户随后按下 'loadMore',则只会加载 2 条新消息,而不是 3 条。 当我们加载 3 条消息,发送 4 条消息,然后检索“另外 3 条消息”时,这个问题会更糟。然后它将只删除第一个...
Question 2: Appending the list of messages:
this.messages 此时是一个 FirebaseListObservable<>。 据我所知,不可能将此列表附加到新检索到的消息中。 我正在考虑创建一个 this.messageObjects (或其他东西),其中包含一组消息对象。每次我检索更多消息时,我都可以附加该数组。 这是一个好主意吗?或者有更好的方法吗?
Additional info
我使用的是 firebase ID (-K3d--f3e2...),所以我不能简单地说 'endAt - 1' 或其他内容。
我现在使用 2 个对象而不是 1 个(1 个数组,包含消息,1 个包含该数组的主题(作为值,而不是作为参考))。
当我检索消息时,我将它们附加到数组并使用此数组(作为值,而不是通过引用)作为主题的参数调用 .next()。这样就可以了!