我正在使用Firebase Firestore数据库制作android聊天应用程序,我需要与侦听器进行无限分页以进行数据更改(新消息,删除消息...)
我发现用kotlin写的博客文章以及corse搜索过的firebase文档,并得到以下代码:
SELECT
TRY_CONVERT(XML, p.query_plan) AS QueryPlan
FROM sys.dm_exec_cached_plans ps
OUTER APPLY sys.dm_exec_text_query_plan(ps.plan_handle, 0, -1) p
现在,代码假设为第一个20条消息和新消息保存侦听器,第二个为20-40个消息保存侦听器,依此类推,但是由于某种原因,它无法正常工作。我想念什么吗?
问题在于那条线
// firstTime variable shows if function is called from pagination or initially
private void addMessagesEventListener(boolean firstTime) {
// get collection
CollectionReference messagesCollection = chatsCollection.document(chat.getId()).collection(Constants.FIREBASE_MESSAGES_PATH);
// create query
Query query = messagesCollection.orderBy("timestamp", Query.Direction.DESCENDING);
// if NOT first time add startAt
if (!firstTime) {
query.startAt(startTimestamp);
}
//limit to 20 messages
query.limit(20).get().addOnSuccessListener(queryDocumentSnapshots -> {
if (!firstTime) {
endTimestamp = startTimestamp;
}
startTimestamp = (long) queryDocumentSnapshots.getDocuments().get(queryDocumentSnapshots.size() - 1).get("timestamp");
Query innerQuery = messagesCollection.orderBy("timestamp").startAt(startTimestamp);
if(!firstTime) {
innerQuery.endBefore(endTimestamp);
}
ListenerRegistration listener = innerQuery
.addSnapshotListener((queryDocumentSnapshots1, e) -> {
if (e != null) {
Log.w(TAG, "listen:error", e);
return;
}
for (DocumentChange dc : queryDocumentSnapshots1.getDocumentChanges()) {
Message message = dc.getDocument().toObject(Message.class);
switch (dc.getType()) {
case ADDED:
// add new message to list
messageListAdapter.addMessage(message);
if (firstTime) {
messagesList.smoothScrollToPosition(0);
}
break;
case REMOVED:
// remove message from list
messageListAdapter.removeMessage(message);
break;
}
}
});
listeners.add(listener);
});
}
总是得到相同的结果。我什至尝试使用documentSnapshot代替时间戳,结果相同。
谢谢。
答案 0 :(得分:1)
尝试
@Override
public void onStart() {
super.onStart();
loadFirstQuery();
}
public void loadFirstQuery() {
if (firebaseAuth.getCurrentUser() != null) {
contentListDashboard.clear();
String currentUserId = firebaseAuth.getCurrentUser().getUid();
// what we do when recycler reach bottom
recyclerProfileDashboard.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// horizontal
//Boolean reachBottom = !recyclerView.canScrollHorizontally(-1);
// for vertical recycler
Boolean reachBottom = !recyclerView.canScrollVertically(-1);
if (reachBottom) {
loadMorePost(); // do load more post
}
}
});
// RETRIEVING FIRST Query
Query firstQuery = firebaseFirestore
.collection("ProfileDashboard")
.document(currentUserId)
.collection("ProfileInfo")
.orderBy("timestamp", Query.Direction.DESCENDING)
.limit(20);
firstQuery.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
if (!documentSnapshots.isEmpty()) {
// please add if doc not empty
if (isFirstPageFirstLoad) {
lastVisible = documentSnapshots.getDocuments().get(documentSnapshots.size() - 1); // array 0, 1, 2
}
for (DocumentChange doc : documentSnapshots.getDocumentChanges()) {
if (doc.getType() == DocumentChange.Type.ADDED) {
//String postId = doc.getDocument().getId();
contentProfileDashboard = doc.getDocument().toObject(ContentProfileDashboard.class);
// if first page firest load true
if (isFirstPageFirstLoad) {
contentListDashboard.add(contentProfileDashboard);
} else {
contentListDashboard.add(0, contentProfileDashboard);
}
// fire the event
adapterProfileDashboard.notifyDataSetChanged();
}
}
isFirstPageFirstLoad = false;
}
}
});
}
}
// Method to load more post
public void loadMorePost() {
if (firebaseAuth.getCurrentUser() != null) {
String currentUserId = firebaseAuth.getCurrentUser().getUid();
Query nextQuery = firebaseFirestore
.collection("ProfileDashboard")
.document(currentUserId)
.collection("ProfileInfo")
.orderBy("timestamp", Query.Direction.DESCENDING)
.startAfter(lastVisible)
.limit(20);
nextQuery.addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(QuerySnapshot documentSnapshots, FirebaseFirestoreException e) {
if (!documentSnapshots.isEmpty()) {
lastVisible = documentSnapshots.getDocuments().get(documentSnapshots.size() - 1);
for (DocumentChange doc : documentSnapshots.getDocumentChanges()) {
if (doc.getType() == DocumentChange.Type.ADDED) {
//String postId = doc.getDocument().getId();
// contentSeen = doc.getDocument().toObject(ContentProfile.class);
// contentList.add(contentSeen);
contentProfileDashboard = doc.getDocument().toObject(ContentProfileDashboard.class);
contentListDashboard.add(contentProfileDashboard);
//adapterSeen.notifyDataSetChanged();
adapterProfileDashboard.notifyDataSetChanged();
}
}
}
}
});
}
}
有什么问题吗?
答案 1 :(得分:1)
我发现了错误。 工作代码为:
private void addMessagesEventListener(boolean firstTime) {
CollectionReference messagesCollection = chatsCollection.document(chat.getId()).collection(Constants.FIREBASE_MESSAGES_PATH);
Query query = messagesCollection.orderBy("timestamp", Query.Direction.DESCENDING);
if (!firstTime) {
query = query.startAt(startListen);
}
query.limit(20).get().addOnSuccessListener(queryDocumentSnapshots -> {
if (!firstTime) {
endListen = startListen;
}
startListen = queryDocumentSnapshots.getDocuments().get(queryDocumentSnapshots.size() - 1);
Query innerQuery = messagesCollection.orderBy("timestamp").startAt(startListen);
if(!firstTime) {
innerQuery = innerQuery.endBefore(endListen);
}
ListenerRegistration listener = innerQuery
.addSnapshotListener((queryDocumentSnapshots1, e) -> {
if (e != null) {
Log.w("SASA", "listen:error", e);
return;
}
for (DocumentChange dc : queryDocumentSnapshots1.getDocumentChanges()) {
Message message = dc.getDocument().toObject(Message.class);
switch (dc.getType()) {
case ADDED:
// add new message to list
messageListAdapter.addMessage(message);
if (firstTime) {
messagesList.smoothScrollToPosition(0);
}
break;
case REMOVED:
// remove message from list
messageListAdapter.removeMessage(message);
break;
}
}
});
listeners.add(listener);
});
}
错误出在query = query.startAt(startListen)
和innerQuery = innerQuery.endBefore(endListen)
您应该添加
private void detachListeners() {
for(ListenerRegistration registration : listeners) {
registration.remove();
}
}
在onDestroy中分离所有侦听器。
代码正在侦听添加和删除旧消息。