【问题标题】:Get Realtime-Update of an Array of DocumentReferences获取文档引用数组的实时更新
【发布时间】:2019-06-22 12:11:28
【问题描述】:

我正在编写一个游戏,用户可以在其中加入一个大厅一起玩。因此我更新了存储在 Firestore 中的大厅和用户。 Lobby-Collection 中的 Lobbys 包含一个 Id、creator、creationDate 和所有成员的数组(对用户集合中的用户对象的文档引用)。用户包含 ID、姓名、邮件和活动大厅。现在,当我更新 Firestore 中的条目时,在那里(Firestore)它们似乎是正确的.. 但是当我收到 realtimeUpdate(通过添加 SnapshotListener)时,成员数组似乎是空的.. 但我只是插入了用户到阵列,他们被保存到 Firestore..

也许很高兴知道:我将从 Firestore 获得的数据集转换为本地 Java 对象,以便更好地处理 UI 内容

我还有一个本地 HashMap 来或多或少地缓存对象,所以我不必总是从 Firestore 加载(我知道 Firestore 库中已经有一个缓存......但我想我需要自己的)

目前,我将更改直接写入 Firestore,并等待它们通过 RealtimeUpdate 返回,然后更新我的本地对象。我还尝试更新我的本地对象,然后将它们写入 Firestore.. 但是我只将我的用户附加到成员数组中,并且该数组包含同一用户的多个引用..

/**
     * 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 仅提供“正常”数据,但不提供引用数组。当我最初从 Firestore 加载数据时,我得到了 Firestore 的实际数据(非空)。但我想获取整个文档,包括“正常”数据(id、creationDate、...)和整个成员数组。

我已经花了 1.5 天的时间来解决这个问题,我无法弄清楚,出了什么问题..

【问题讨论】:

    标签: android google-cloud-firestore real-time-updates


    【解决方案1】:

    没关系,我弄错了....真是愚蠢的一个^^

    在我更新对象的部分中,当 Firestore 更改时……我使用了错误/旧的 DocumentSnapshot。所以我使用了最初的成员​​数组,而不是我新更新的:D

    应该是:

    List<DocumentReference> update_docmems = (List<DocumentReference>) snapshot.get(FIRESTORE_DOCUMENT_MEMBER);
    

    代替:

    List<DocumentReference> update_docmems = (List<DocumentReference>) documentSnapshot.get(FIRESTORE_DOCUMENT_MEMBER);
    

    现在我得到了正确的更新:D

    【讨论】:

      猜你喜欢
      • 2017-01-19
      • 2020-11-18
      • 2015-04-07
      • 2020-12-03
      • 1970-01-01
      • 1970-01-01
      • 2014-04-01
      • 2018-09-27
      • 1970-01-01
      相关资源
      最近更新 更多