> ## Documentation Index
> Fetch the complete documentation index at: https://learn.social.plus/llms.txt
> Use this file to discover all available pages before exploring further.

# Get User Information

> Retrieve user profiles by ID, batch user lookups where supported, and query paginated user collections.

Retrieve user profiles for profile screens, user cards, and directory views with the user repository. Use the single-user API when you know the exact user ID, batch lookup when your SDK exposes `getUserByIds`, and `getUsers()` when you need a sorted list instead of a fixed set of IDs.

<Info>
  iOS and TypeScript expose live-object or live-collection wrappers for user observation. Android uses `Flowable<T>` for the same operations, while Flutter returns `Future<AmityUser>` for `getUser(userId)` and query builders for paginated collections.
</Info>

## Parameters

This page covers three user-read operations. Use this table to choose the operation first, then use the inputs table in each section for the exact SDK call shape.

| Operation                | Use when                                                                   | Required inputs                               | Platforms                         |
| ------------------------ | -------------------------------------------------------------------------- | --------------------------------------------- | --------------------------------- |
| Get a single user        | You already know one user ID and need that profile.                        | `userId`                                      | TypeScript, iOS, Android, Flutter |
| Get multiple users by ID | You already have a fixed set of user IDs and need those profiles together. | `userIds`                                     | TypeScript, Android               |
| Query users              | You need a sorted or paginated user list rather than a fixed set of IDs.   | None globally; sort options vary by platform. | TypeScript, iOS, Android, Flutter |

## Get a single user

Use the single-user API when your app already knows the user ID and needs the latest profile details for that specific user. The examples below show the native return shape for each SDK.

### Inputs

| Platform   | Method                                                | Required inputs    | Result shape                                                     |
| ---------- | ----------------------------------------------------- | ------------------ | ---------------------------------------------------------------- |
| TypeScript | `UserRepository.getUser(userId, callback)`            | `userId`, callback | Starts a live observer and returns an unsubscriber.              |
| iOS        | `userRepository.getUser(userId)`                      | `userId`           | Returns a live object observed with an `AmityNotificationToken`. |
| Android    | `userRepository.getUser(userId)`                      | `userId`           | Returns `Flowable<AmityUser>`.                                   |
| Flutter    | `AmityCoreClient.newUserRepository().getUser(userId)` | `userId`           | Returns `Future<AmityUser>`.                                     |

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { UserRepository } from '@amityco/ts-sdk';

  const unsubscribe = UserRepository.getUser('user_123', ({ data: user, loading, error }) => {
    if (loading) return;

    if (error || !user) {
      console.error('Failed to get user', error);
      return;
    }

    console.log(user.userId, user.displayName);
  });

  // Call unsubscribe() when the screen no longer needs user updates.
  ```

  ```swift iOS theme={null}
  var token: AmityNotificationToken?

  func observeUser() {
      let liveObject = userRepository.getUser("user_123")
      token = liveObject.observe { liveObject, error in
          guard let user = liveObject.snapshot else {
              print("error: \(String(describing: error))")
              return
          }

          print("userId: \(user.userId), displayName: \(String(describing: user.displayName))")
      }
  }
  ```

  ```kotlin Android theme={null}
  fun getUser(userRepository: AmityUserRepository) {
      userRepository.getUser(userId = "user_123")
          .doOnNext { user: AmityUser ->
              val displayName = user.getDisplayName()
              val userId = user.getUserId()
              Log.d("UserRepo", "User: $displayName ($userId)")
          }
          .doOnError { error ->
              Log.e("UserRepo", "Failed to get user", error)
          }
          .subscribe()
  }
  ```

  ```dart Flutter theme={null}
  Future<void> getUser() async {
    try {
      final user = await AmityCoreClient.newUserRepository().getUser('user_123');
      print('User: ${user.displayName}');
    } on AmityException catch (error) {
      print('Failed to get user: $error');
    }
  }
  ```
</CodeGroup>

## Get multiple users by ID

Use batch lookup when your app already has a fixed set of user IDs and needs those profiles together. This API is available on TypeScript and Android. For browse flows, use the query operation below.

### Inputs

| Platform   | Method                                 | Required inputs        | Result shape                             |
| ---------- | -------------------------------------- | ---------------------- | ---------------------------------------- |
| TypeScript | `UserRepository.getUserByIds(userIds)` | `userIds: string[]`    | Returns a promise with cached user data. |
| Android    | `userRepository.getUserByIds(userIds)` | `userIds: Set<String>` | Returns `Flowable<List<AmityUser>>`.     |

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { UserRepository } from '@amityco/ts-sdk';

  async function getUsersByIds() {
    const userIds = ['user_123', 'user_456'];
    const { data: users } = await UserRepository.getUserByIds(userIds);

    users.forEach(user => {
      console.log(user.userId, user.displayName);
    });
  }
  ```

  ```kotlin Android theme={null}
  fun getUsersByIds(
      userRepository: AmityUserRepository,
      userIds: Set<String>
  ) {
      userRepository.getUserByIds(userIds = userIds)
          .doOnNext { users: List<AmityUser> ->
              users.forEach { user ->
                  Log.d("UserRepo", "User: ${user.getDisplayName()}")
              }
          }
          .doOnError { error ->
              Log.e("UserRepo", "Failed to get users", error)
          }
          .subscribe()
  }
  ```
</CodeGroup>

## Query users

Use `getUsers()` when you need a sorted, paginated user list for browse flows such as user directories, member pickers, or moderation tools. On TypeScript, the live collection callback also exposes `hasNextPage` and `onNextPage` when more results are available.

### Inputs

| Platform   | Method                                           | Required inputs | Optional inputs                    | Result shape                                                         |
| ---------- | ------------------------------------------------ | --------------- | ---------------------------------- | -------------------------------------------------------------------- |
| TypeScript | `UserRepository.getUsers(params, callback)`      | callback        | `sortBy`, `limit`                  | Starts a live collection observer and returns an unsubscriber.       |
| iOS        | `userRepository.getUsers(sortBy)`                | sort option     | None in this call shape            | Returns a live collection observed with an `AmityNotificationToken`. |
| Android    | `userRepository.getUsers().build().query()`      | None            | `sortBy(...)`                      | Returns `Flowable<PagingData<AmityUser>>`.                           |
| Flutter    | `AmityCoreClient.newUserRepository().getUsers()` | None            | `sortBy(...)`, paging token, limit | Returns paging data through the query builder.                       |

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { UserRepository } from '@amityco/ts-sdk';

  let loadMoreUsers: (() => void) | undefined;

  const unsubscribe = UserRepository.getUsers(
    { sortBy: 'lastCreated' },
    ({ data: users, loading, error, hasNextPage, onNextPage }) => {
      if (loading) return;

      if (error) {
        console.error('Failed to query users', error);
        return;
      }

      console.log(`Loaded ${users.length} users`);
      console.log(`More pages available: ${hasNextPage}`);
      loadMoreUsers = onNextPage;
    },
  );

  // Call loadMoreUsers?.() from your load-more action.
  // Call unsubscribe() when the screen no longer needs user list updates.
  ```

  ```swift iOS theme={null}
  var token: AmityNotificationToken?

  func queryUsersExample() {
      let liveCollection = userRepository.getUsers(.displayName)
      token = liveCollection.observe { collection, error in
          let users = collection.snapshots
          print("Loaded \(users.count) users")
      }
  }
  ```

  ```kotlin Android theme={null}
  fun queryUsers(userRepository: AmityUserRepository) {
      userRepository.getUsers()
          .sortBy(sortOption = AmityUserSortOption.DISPLAYNAME) // optional
          .build()
          .query()
          .doOnNext { users: PagingData<AmityUser> ->
              // PagingData<AmityUser>
          }
          .doOnError {
              // Exception
          }
          .subscribe()
  }
  ```

  ```dart Flutter theme={null}
  final _amityUsers = <AmityUser>[];
  late PagingController<AmityUser> _amityUsersController;

  void getUsers(AmityUserSortOption amityUserSortOption) {
    _amityUsersController = PagingController(
      pageFuture: (token) => AmityCoreClient.newUserRepository()
          .getUsers()
          .sortBy(amityUserSortOption)
          .getPagingData(token: token, limit: 20),
      pageSize: 20,
    )..addListener(
        () {
          if (_amityUsersController.error == null) {
            _amityUsers.clear();
            _amityUsers.addAll(_amityUsersController.loadedItems);
          }
        },
      );
  }
  ```
</CodeGroup>

## Platform notes

* `getUserByIds(userIds)` is public on TypeScript and Android, but not on iOS or Flutter.
* TypeScript `getUser(...)` and `getUsers(...)` start live observers and return unsubscriber functions when your screen no longer needs updates.
* Android uses `Flowable<AmityUser>` for single-user observation and `Flowable<List<AmityUser>>` for batch lookup.
* Flutter `getUser(userId)` is a one-time `Future<AmityUser>`. If you need stream-based observation there, use `AmityCoreClient.newUserRepository().live.getUser(userId)`.

## Related topics

<CardGroup cols={2}>
  <Card title="Search and Query Users" href="./search-and-query-users" icon="user-magnifying-glass">
    Search users by display name and query user collections.
  </Card>

  <Card title="Update User Information" href="./update-user-information" icon="user-pen">
    Update the authenticated user's profile data.
  </Card>
</CardGroup>
