获取文档引用数组的实时更新
Get Realtime-Update of an Array of DocumentReferences
我正在写一个游戏,用户可以加入一个大厅一起玩。因此,我更新了存储在 Firestore 中的大厅和用户。 Lobby-Collection 中的 Lobbys 包含 Id、creator、creationDate 和所有成员的数组(用户集合中用户对象的 DocumentReferences)。用户包含一个 ID、名称、邮件和一个活动的大厅。现在,当我更新 Firestore 中的条目时,在那里(Firestore)它们似乎是正确的..但是当我收到 realtimeUpdate(通过添加 SnapshotListener)时,成员数组似乎是空的..但我只是插入了阵列的用户,他们被保存到 Firestore..
也许很高兴知道:我将从 Firestore 获得的数据集转换为本地 Java-对象,以便更好地处理 UI 事物
我还有一个本地 HashMap 来或多或少地缓存对象,所以我不必总是从 Firestore 加载(我知道 Firestore 库中已经有一个缓存..但我想我需要我自己的)
目前我将更改直接写入 Firestore 并等待它们通过 RealtimeUpdate 返回,然后更新我的本地对象。我还尝试更新我的本地对象,然后将它们写入 Firestore.. 但后来我只将我的用户附加到 Members-Array,并且该数组包含同一用户的多个引用..
/**
* Get a Lobby Object from a DocumentSnapshot from Firestrore
* If the Object already exists it will be loaded from the "CacheMap"
*
* @param documentSnapshot DocumentSnapshot with the data from the Firestore
* @param feedback a method to call when the Lobby was retrieved
*/
public static void getLobbyByDocSnap(DocumentSnapshot documentSnapshot, IFeedback feedback) {
final String METHOD = TAG + " #getLobbyByDocSnap";
String lobby_id = documentSnapshot.getString(FIRESTORE_DOCUMENT_ID);
if (allLoadedLobbys.containsKey(lobby_id)) {
Log.d(METHOD, "found object in map for id: " + lobby_id);
feedback.trigger(allLoadedLobbys.get(lobby_id));
return;
}
Log.d(METHOD, "Could not find in Map.. generate through data");
Lobby lobby = new Lobby();
lobby.setId(lobby_id);
lobby.setPrivateLobby(documentSnapshot.getBoolean(FIRESTORE_DOCUMENT_PRIVATELOBBY));
lobby.setCreationDate(documentSnapshot.getDate(FIRESTORE_DOCUMENT_CREATIONDATE));
allLoadedLobbys.put(lobby.getId(), lobby);
//create all Members of the Lobby as User Objects
final List<User> members = new ArrayList<>();
List<DocumentReference> docmems = (List<DocumentReference>) documentSnapshot.get(FIRESTORE_DOCUMENT_MEMBER);
Log.d(METHOD, "get all members of lobby: " + lobby_id);
for (final DocumentReference docmem : docmems) {
/*docmem.collection(FIRESTORE_DOCUMENT_MEMBER).get()
.addOnSuccessListener(queryDocumentSnapshots -> {
Log.d(METHOD, "Found Members for: "+lobby_id+": "+Arrays.toString(queryDocumentSnapshots.getDocuments().toArray()));
//Convert DocumentReference to User-Object
for (DocumentSnapshot document : queryDocumentSnapshots.getDocuments()) {
Log.d(METHOD, "Get User Object from "+UserManager.class.getCanonicalName());
UserManager.getUserByDocSnap(document, o -> members.add((User) o));
}
});*/
UserManager.getUserByRef(docmem, o -> members.add((User) o));
}
lobby.setMember(members);
Log.d(METHOD, "Start getting the Creator of this Lobby: " + lobby_id);
//create an User-Object for the Creator
UserManager.getUserByRef((DocumentReference) documentSnapshot.get(FIRESTORE_DOCUMENT_CREATOR), o -> {
User creator = (User) o;
lobby.setCreator(creator);
Log.d(METHOD, "Got the Creator, now get the artist for: " + lobby_id);
UserManager.getUserByRef((DocumentReference) documentSnapshot.get(FIRESTORE_DOCUMENT_ARTIST), a -> {
User artist = (User) a;
Log.d(METHOD, "Got the Artist. All Infos collected for: " + lobby_id);
//Create The Lobby-Object
lobby.setArtist(artist);
Log.d(METHOD, "Save the Lobby to the CacheMap: " + lobby.toString());
//add it to the given list and trigger the feedback
feedback.trigger(lobby);
});
});
documentSnapshot.getReference().addSnapshotListener((snapshot, e) -> {
if (e != null) {
Log.w(METHOD+"+new", "Listen failed.", e);
return;
}
if (snapshot != null && snapshot.exists()) {
Log.d(METHOD + "*new", "Current data: " + snapshot.getData());
String update_lobby_id = snapshot.getString(FIRESTORE_DOCUMENT_ID);
Lobby update_lobby = allLoadedLobbys.get(update_lobby_id);
update_lobby.setCreationDate(snapshot.getDate(FIRESTORE_DOCUMENT_CREATIONDATE));
update_lobby.setPrivateLobby(snapshot.getBoolean(FIRESTORE_DOCUMENT_PRIVATELOBBY));
UserManager.getUserByRef(snapshot.getDocumentReference(FIRESTORE_DOCUMENT_ARTIST), o -> update_lobby.setArtist((User) o));
UserManager.getUserByRef(snapshot.getDocumentReference(FIRESTORE_DOCUMENT_CREATOR), o -> update_lobby.setCreator((User) o));
List<User> update_member = update_lobby.getMember();
update_member.clear();
List<DocumentReference> update_docmems = (List<DocumentReference>) documentSnapshot.get(FIRESTORE_DOCUMENT_MEMBER);
//update_lobby.setMember(update_member);
Log.d(METHOD+"*new", "get all updated members of lobby: " + update_lobby_id);
Log.d(METHOD+"*new", "members DocRef List: " + update_docmems);
/*for (final DocumentReference update_docmem : update_docmems) {
Log.d(METHOD+"*new", update_docmem.getId());
UserManager.getUserByRef(update_docmem, o -> {
Log.d(METHOD+"*new",((User) o).toString());
update_lobby.addMember((User) o);
});
}*/
getMemberList(update_docmems, new ArrayList<>(), o -> {
List<User> mems = (List<User>) o;
update_lobby.getMember().clear();
update_lobby.getMember().addAll(mems);
});
} else {
Log.d(METHOD+"*new", "Current data: null");
}
});
}
private static void getMemberList(List<DocumentReference> update_docmems, List<User> member, IFeedback feedback){
final String METHOD = TAG + " #getMemberList";
/*if(null == member){
member = new ArrayList<>();
}*/
if(update_docmems.isEmpty()){
feedback.trigger(member);
return;
}
DocumentReference docref = update_docmems.get(0);
UserManager.getUserByRef(docref, o -> {
member.add((User) o);
Log.d(METHOD, o.toString());
update_docmems.remove(0);
getMemberList(update_docmems, member, feedback);
});
}
Realtime 仅提供 "normal" 数据,但不提供引用数组。当我最初从 Firestore 加载数据时,我得到了 Firestore 的实际数据(不是空的)。但我想获取整个文档,包括 "normal" 数据(id、creationDate、...)和整个成员数组。
我已经用了 1.5 天时间来解决这个问题,我想不通,怎么了..
没关系,我得到了我的错误....真的很愚蠢^^
在我更新我的对象的部分,当 firestore 发生变化时..我使用了 wrong/old DocumentSnapshot。所以我使用了初始 Members-Array 而不是我新更新的 :D
应该是:
List<DocumentReference> update_docmems = (List<DocumentReference>) snapshot.get(FIRESTORE_DOCUMENT_MEMBER);
而不是:
List<DocumentReference> update_docmems = (List<DocumentReference>) documentSnapshot.get(FIRESTORE_DOCUMENT_MEMBER);
现在我可以正确获取更新了:D
我正在写一个游戏,用户可以加入一个大厅一起玩。因此,我更新了存储在 Firestore 中的大厅和用户。 Lobby-Collection 中的 Lobbys 包含 Id、creator、creationDate 和所有成员的数组(用户集合中用户对象的 DocumentReferences)。用户包含一个 ID、名称、邮件和一个活动的大厅。现在,当我更新 Firestore 中的条目时,在那里(Firestore)它们似乎是正确的..但是当我收到 realtimeUpdate(通过添加 SnapshotListener)时,成员数组似乎是空的..但我只是插入了阵列的用户,他们被保存到 Firestore..
也许很高兴知道:我将从 Firestore 获得的数据集转换为本地 Java-对象,以便更好地处理 UI 事物
我还有一个本地 HashMap 来或多或少地缓存对象,所以我不必总是从 Firestore 加载(我知道 Firestore 库中已经有一个缓存..但我想我需要我自己的)
目前我将更改直接写入 Firestore 并等待它们通过 RealtimeUpdate 返回,然后更新我的本地对象。我还尝试更新我的本地对象,然后将它们写入 Firestore.. 但后来我只将我的用户附加到 Members-Array,并且该数组包含同一用户的多个引用..
/**
* Get a Lobby Object from a DocumentSnapshot from Firestrore
* If the Object already exists it will be loaded from the "CacheMap"
*
* @param documentSnapshot DocumentSnapshot with the data from the Firestore
* @param feedback a method to call when the Lobby was retrieved
*/
public static void getLobbyByDocSnap(DocumentSnapshot documentSnapshot, IFeedback feedback) {
final String METHOD = TAG + " #getLobbyByDocSnap";
String lobby_id = documentSnapshot.getString(FIRESTORE_DOCUMENT_ID);
if (allLoadedLobbys.containsKey(lobby_id)) {
Log.d(METHOD, "found object in map for id: " + lobby_id);
feedback.trigger(allLoadedLobbys.get(lobby_id));
return;
}
Log.d(METHOD, "Could not find in Map.. generate through data");
Lobby lobby = new Lobby();
lobby.setId(lobby_id);
lobby.setPrivateLobby(documentSnapshot.getBoolean(FIRESTORE_DOCUMENT_PRIVATELOBBY));
lobby.setCreationDate(documentSnapshot.getDate(FIRESTORE_DOCUMENT_CREATIONDATE));
allLoadedLobbys.put(lobby.getId(), lobby);
//create all Members of the Lobby as User Objects
final List<User> members = new ArrayList<>();
List<DocumentReference> docmems = (List<DocumentReference>) documentSnapshot.get(FIRESTORE_DOCUMENT_MEMBER);
Log.d(METHOD, "get all members of lobby: " + lobby_id);
for (final DocumentReference docmem : docmems) {
/*docmem.collection(FIRESTORE_DOCUMENT_MEMBER).get()
.addOnSuccessListener(queryDocumentSnapshots -> {
Log.d(METHOD, "Found Members for: "+lobby_id+": "+Arrays.toString(queryDocumentSnapshots.getDocuments().toArray()));
//Convert DocumentReference to User-Object
for (DocumentSnapshot document : queryDocumentSnapshots.getDocuments()) {
Log.d(METHOD, "Get User Object from "+UserManager.class.getCanonicalName());
UserManager.getUserByDocSnap(document, o -> members.add((User) o));
}
});*/
UserManager.getUserByRef(docmem, o -> members.add((User) o));
}
lobby.setMember(members);
Log.d(METHOD, "Start getting the Creator of this Lobby: " + lobby_id);
//create an User-Object for the Creator
UserManager.getUserByRef((DocumentReference) documentSnapshot.get(FIRESTORE_DOCUMENT_CREATOR), o -> {
User creator = (User) o;
lobby.setCreator(creator);
Log.d(METHOD, "Got the Creator, now get the artist for: " + lobby_id);
UserManager.getUserByRef((DocumentReference) documentSnapshot.get(FIRESTORE_DOCUMENT_ARTIST), a -> {
User artist = (User) a;
Log.d(METHOD, "Got the Artist. All Infos collected for: " + lobby_id);
//Create The Lobby-Object
lobby.setArtist(artist);
Log.d(METHOD, "Save the Lobby to the CacheMap: " + lobby.toString());
//add it to the given list and trigger the feedback
feedback.trigger(lobby);
});
});
documentSnapshot.getReference().addSnapshotListener((snapshot, e) -> {
if (e != null) {
Log.w(METHOD+"+new", "Listen failed.", e);
return;
}
if (snapshot != null && snapshot.exists()) {
Log.d(METHOD + "*new", "Current data: " + snapshot.getData());
String update_lobby_id = snapshot.getString(FIRESTORE_DOCUMENT_ID);
Lobby update_lobby = allLoadedLobbys.get(update_lobby_id);
update_lobby.setCreationDate(snapshot.getDate(FIRESTORE_DOCUMENT_CREATIONDATE));
update_lobby.setPrivateLobby(snapshot.getBoolean(FIRESTORE_DOCUMENT_PRIVATELOBBY));
UserManager.getUserByRef(snapshot.getDocumentReference(FIRESTORE_DOCUMENT_ARTIST), o -> update_lobby.setArtist((User) o));
UserManager.getUserByRef(snapshot.getDocumentReference(FIRESTORE_DOCUMENT_CREATOR), o -> update_lobby.setCreator((User) o));
List<User> update_member = update_lobby.getMember();
update_member.clear();
List<DocumentReference> update_docmems = (List<DocumentReference>) documentSnapshot.get(FIRESTORE_DOCUMENT_MEMBER);
//update_lobby.setMember(update_member);
Log.d(METHOD+"*new", "get all updated members of lobby: " + update_lobby_id);
Log.d(METHOD+"*new", "members DocRef List: " + update_docmems);
/*for (final DocumentReference update_docmem : update_docmems) {
Log.d(METHOD+"*new", update_docmem.getId());
UserManager.getUserByRef(update_docmem, o -> {
Log.d(METHOD+"*new",((User) o).toString());
update_lobby.addMember((User) o);
});
}*/
getMemberList(update_docmems, new ArrayList<>(), o -> {
List<User> mems = (List<User>) o;
update_lobby.getMember().clear();
update_lobby.getMember().addAll(mems);
});
} else {
Log.d(METHOD+"*new", "Current data: null");
}
});
}
private static void getMemberList(List<DocumentReference> update_docmems, List<User> member, IFeedback feedback){
final String METHOD = TAG + " #getMemberList";
/*if(null == member){
member = new ArrayList<>();
}*/
if(update_docmems.isEmpty()){
feedback.trigger(member);
return;
}
DocumentReference docref = update_docmems.get(0);
UserManager.getUserByRef(docref, o -> {
member.add((User) o);
Log.d(METHOD, o.toString());
update_docmems.remove(0);
getMemberList(update_docmems, member, feedback);
});
}
Realtime 仅提供 "normal" 数据,但不提供引用数组。当我最初从 Firestore 加载数据时,我得到了 Firestore 的实际数据(不是空的)。但我想获取整个文档,包括 "normal" 数据(id、creationDate、...)和整个成员数组。
我已经用了 1.5 天时间来解决这个问题,我想不通,怎么了..
没关系,我得到了我的错误....真的很愚蠢^^
在我更新我的对象的部分,当 firestore 发生变化时..我使用了 wrong/old DocumentSnapshot。所以我使用了初始 Members-Array 而不是我新更新的 :D
应该是:
List<DocumentReference> update_docmems = (List<DocumentReference>) snapshot.get(FIRESTORE_DOCUMENT_MEMBER);
而不是:
List<DocumentReference> update_docmems = (List<DocumentReference>) documentSnapshot.get(FIRESTORE_DOCUMENT_MEMBER);
现在我可以正确获取更新了:D