Firestore 文档的子事件侦听器和多个用户一次写入文档?
Child Event listener for a Firestore document and Multiple users write to a document at once?
有没有办法为 Firestore 文档实现 ChildEventListener(即,当向文档添加/删除字段时,必须触发一个只获取 added/deleted 字段快照的侦听器)。最好,它必须具有 OnChildAdded、OnChildChanged 和 OnChildDeleted 功能,类似于 Firebase 实时数据库。
另外,有没有办法让多个用户同时操作一个 Firestore 文档而不会发生冲突?? (例如,用户 1、2 和 3 同时将他们的名字添加到同一个文档中)。您能否在 Android 中提供此实现?
在 Cloud Firestore 中,文档的字段不会像处理实时数据库路径时那样被视为文档的 "children",因此无法完全按照您的意愿进行操作。
虽然您可以收听文档的实时更改,并自己实施差异以找出更改的字段:
final DocumentReference docRef = db.collection("cities").document("SF");
docRef.addSnapshotListener(new EventListener<DocumentSnapshot>() {
@Override
public void onEvent(@Nullable DocumentSnapshot snapshot,
@Nullable FirebaseFirestoreException e) {
if (e != null) {
Log.w(TAG, "Listen failed.", e);
return;
}
// ... calculate which fields changed ...
}
});
这是在 FireStore 中的操作方法,您需要使用 ADDED、MODIFIED、REMOVED 枚举。
//Listener
update_listener = mDatabase.collection("Announcements").addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@javax.annotation.Nullable QuerySnapshot queryDocumentSnapshots, @javax.annotation.Nullable FirebaseFirestoreException e) {
//If something went wrong
if (e != null)
Log.w(TAG, "ERROR : ", e);
if (queryDocumentSnapshots != null && !queryDocumentSnapshots.isEmpty()) {
//Instead of simply using the entire query snapshot
//See the actual changes to query results between query snapshots (added, removed, and modified)
for (DocumentChange doc : queryDocumentSnapshots.getDocumentChanges()) {
switch (doc.getType()) {
case ADDED:
if (!isFirstListLoaded){
//Call the model to populate it with document
AnnouncementModel annonPost = doc.getDocument().toObject(AnnouncementModel.class)
.withId(doc.getDocument().getId());
//This will be called only if user added some new post
announcementList.add(0, annonPost);
announcementRecyclerAdapter.notifyItemInserted(0);
//Notify the adapter to update all position
announcementRecyclerAdapter.notifyItemRangeChanged(0, announcementList.size());
Log.d(TAG,"THIS SHOULD BE CALLED");
/* //Just call this method once
if (noContent.isShown()){
//This will be called only if user added some new post
announcementList.add(annonPost);
announcementRecyclerAdapter.notifyDataSetChanged();
noContent.setVisibility(View.GONE);
label.setVisibility(View.VISIBLE);
}*/
}
break;
case MODIFIED:
break;
case REMOVED:
//Get the document ID of post in FireStore
//Perform a loop and scan the list of announcement to target the correct index
for (int i = 0; i < announcementList.size(); i++) {
//Check if the deleted document ID is equal or exist in the list of announcement
if (doc.getDocument().getId().equals(announcementList.get(i).AnnouncementsID)) {
//If yes then delete that object in list by targeting its index
Log.d(TAG, "Removed Post: " + announcementList.get(i).getTitle());
announcementList.remove(i);
//Notify the adapter that some item gets remove
announcementRecyclerAdapter.notifyItemRemoved(i);
//Notify the adapter to update all position
announcementRecyclerAdapter.notifyItemRangeChanged(i, announcementList.size());
break;
}
}
break;
}
}
isFirstListLoaded = false;
}
}
});
有没有办法为 Firestore 文档实现 ChildEventListener(即,当向文档添加/删除字段时,必须触发一个只获取 added/deleted 字段快照的侦听器)。最好,它必须具有 OnChildAdded、OnChildChanged 和 OnChildDeleted 功能,类似于 Firebase 实时数据库。
另外,有没有办法让多个用户同时操作一个 Firestore 文档而不会发生冲突?? (例如,用户 1、2 和 3 同时将他们的名字添加到同一个文档中)。您能否在 Android 中提供此实现?
在 Cloud Firestore 中,文档的字段不会像处理实时数据库路径时那样被视为文档的 "children",因此无法完全按照您的意愿进行操作。
虽然您可以收听文档的实时更改,并自己实施差异以找出更改的字段:
final DocumentReference docRef = db.collection("cities").document("SF");
docRef.addSnapshotListener(new EventListener<DocumentSnapshot>() {
@Override
public void onEvent(@Nullable DocumentSnapshot snapshot,
@Nullable FirebaseFirestoreException e) {
if (e != null) {
Log.w(TAG, "Listen failed.", e);
return;
}
// ... calculate which fields changed ...
}
});
这是在 FireStore 中的操作方法,您需要使用 ADDED、MODIFIED、REMOVED 枚举。
//Listener
update_listener = mDatabase.collection("Announcements").addSnapshotListener(new EventListener<QuerySnapshot>() {
@Override
public void onEvent(@javax.annotation.Nullable QuerySnapshot queryDocumentSnapshots, @javax.annotation.Nullable FirebaseFirestoreException e) {
//If something went wrong
if (e != null)
Log.w(TAG, "ERROR : ", e);
if (queryDocumentSnapshots != null && !queryDocumentSnapshots.isEmpty()) {
//Instead of simply using the entire query snapshot
//See the actual changes to query results between query snapshots (added, removed, and modified)
for (DocumentChange doc : queryDocumentSnapshots.getDocumentChanges()) {
switch (doc.getType()) {
case ADDED:
if (!isFirstListLoaded){
//Call the model to populate it with document
AnnouncementModel annonPost = doc.getDocument().toObject(AnnouncementModel.class)
.withId(doc.getDocument().getId());
//This will be called only if user added some new post
announcementList.add(0, annonPost);
announcementRecyclerAdapter.notifyItemInserted(0);
//Notify the adapter to update all position
announcementRecyclerAdapter.notifyItemRangeChanged(0, announcementList.size());
Log.d(TAG,"THIS SHOULD BE CALLED");
/* //Just call this method once
if (noContent.isShown()){
//This will be called only if user added some new post
announcementList.add(annonPost);
announcementRecyclerAdapter.notifyDataSetChanged();
noContent.setVisibility(View.GONE);
label.setVisibility(View.VISIBLE);
}*/
}
break;
case MODIFIED:
break;
case REMOVED:
//Get the document ID of post in FireStore
//Perform a loop and scan the list of announcement to target the correct index
for (int i = 0; i < announcementList.size(); i++) {
//Check if the deleted document ID is equal or exist in the list of announcement
if (doc.getDocument().getId().equals(announcementList.get(i).AnnouncementsID)) {
//If yes then delete that object in list by targeting its index
Log.d(TAG, "Removed Post: " + announcementList.get(i).getTitle());
announcementList.remove(i);
//Notify the adapter that some item gets remove
announcementRecyclerAdapter.notifyItemRemoved(i);
//Notify the adapter to update all position
announcementRecyclerAdapter.notifyItemRangeChanged(i, announcementList.size());
break;
}
}
break;
}
}
isFirstListLoaded = false;
}
}
});