Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MXRoom.members gives incorrect / incomplete results #1204

Open
cvwright opened this issue Aug 18, 2021 · 1 comment
Open

MXRoom.members gives incorrect / incomplete results #1204

cvwright opened this issue Aug 18, 2021 · 1 comment

Comments

@cvwright
Copy link
Contributor

Describe the bug
The MXRoom members() returns an incomplete list of the members in the room.

The bug seems to be that it incorrectly thinks that its timeline has already cached the complete list of members. It returns the list of members from the timeline without querying the homeserver.

For example:

2021-08-18 10:48:59.336539-0500 Circles[21413:991558] [MXRoom] members: roomId: !sTCABYwgCcBxUpcZkb:kombucha.social
2021-08-18 10:48:59.336743-0500 Circles[21413:991558] [MXRoom] members: All members are known. Return 3 joined, 0 invited

But when I query the same room directly using MXRestClient membersOfRoom: withParameters: I see 7 members in state join and one member in state leave.

To Reproduce

  1. Create a room
  2. Join several users into the room, but have only 1 or 2 send messages
  3. Query with MXRoom.members
  4. Query with MXRestClient.membersOfRoom
  5. Compare the two lists of users

Code that I'm using to query the MXRoom:

        mxroom.members { response in
            switch response {
            case .failure(let err):
                let msg = "Failed to get members: \(err)"
                print("ASYNCMEMBERS\t\(msg)")
                completion(.failure(KSError(message: msg)))
            case .success(let maybeMxMembers):
                print("ASYNCMEMBERS\tGot response from Matrix")
                if let members = maybeMxMembers {
                    print("ASYNCMEMBERS\tMatrix returned \(members.members.count) members in room \(self.id)")
                    self.mxMembers = members
                    self.objectWillChange.send()

                    let users = members.joinedMembers.compactMap { mxroommember in
                        self.matrix.getUser(userId: mxroommember.userId)
                    }
                    completion(.success(users))
                } else {
                    completion(.failure(KSError(message: "Matrix returned no members for room \(self.id)")))
                }
            } 
        }

Code that I'm using to query the MXRestClient:

        //let params = [kMXMembersOfRoomParametersMembership: "join"]
        let params = [String:Any]()
        restClient.members(ofRoom: roomId,
                           withParameters: params,
                           success: { result in

                            guard let events = result as? [MXEvent] else {
                                print("MATRIXMEMBERS\tRest client gave us garbage")
                                return
                            }

                                print("MATRIXMEMBERS\tGot \(events.count) state events from Matrix")
                                let users: [MatrixUser] = events.compactMap { event in
                                    guard let userId = event.stateKey,
                                          let userState = event.content["membership"] else {
                                        print("MATRIXMEMBERS\tGot an event without valid membership info")
                                        return nil
                                    }
                                    print("MATRIXMEMBERS\tGot an event for user [\(userId)]")
                                    print("MATRIXMEMBERS\t\(roomId)\t\(userId)\t\(userState)")
                                    return self.getUser(userId: userId)
                                }
                                completion(.success(users))
                            },
                           failure: { error in
                                let msg = "Failed to get room members from the homeserver"
                                print("MATRIXMEMBERS\t\(msg)")
                                let err = KSError(message: msg)
                                completion(.failure(err))
                           }
        )

Expected behavior
The function should return the full list of current members in the room.

Additional context
The room in question is basically a social media "wall" room in Circles, where typically only the owner posts messages.

Maybe the algorithm here fails when there are silent users who have not sent any messages into the room???

  • The 4 users who are missed by MXRoom.members have never sent any messages into the room.
  • At least one (maybe two?) of the users who are picked up by MXRoom.members have also never sent any m.room.messages. It's possible that they have sent other events, like possibly an m.room.member event to set a new avatar image.
@cvwright
Copy link
Contributor Author

Looks like I'm only getting the lazy-loaded members.

The issue seems to be false positives in the store's hasLoadedAllRoomMembersForRoom

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant