// Search for users with id "john", "jack", or "jessie"
val request = QueryUsersRequest(
filter = Filters.`in`("id", listOf("john", "jack", "jessie")),
offset = 0,
limit = 3,
)
client.queryUsers(request).enqueue { result ->
if (result.isSuccess) {
val users: List<User> = result.data()
} else {
// Handle result.error()
}
}
Querying Users
The Query Users method allows you to search for users and see if they are online/offline. The example below shows how you can retrieve the details for 3 users in one API call:
const response = await client.queryUsers({
id: { $in: ["john", "jack", "jessie"] },
});
// Search users with id "john", "jack", or "jessie"
FilterObject filter = Filters.in("id", Arrays.asList("john", "jack", "jessie"));
int offset = 0;
int limit = 3;
QueryUsersRequest request = new QueryUsersRequest(filter, offset, limit);
client.queryUsers(request).enqueue(result -> {
if (result.isSuccess()) {
List<User> users = result.data();
} else {
// Handle result.error()
}
});
let controller = chatClient.userListController(
query: .init(filter: .in(.id, values: ["john", "jack", "jessie"]))
)
controller.synchronize { error in
if let error = error {
// handle error
print(error)
} else {
// access users
print(controller.users)
}
}
$response = $client->queryUsers([ 'id' => ['$in' => ['john', 'jack', 'jessie'] ] ]);
final _result = client.queryUsers(
filter: Filter.in_(['john', 'jack', 'jessie']),
);
Client->QueryUsers(
FFilter::In(TEXT("id"), {TEXT("john"), TEXT("jack"), TEXT("jessie")}),
{}, // Sort
true, // Presence
{}, // Pagination options
[](const TArray<FUserRef>& Users)
{
// Do something with Users
});
var resp = await userClient.QueryAsync(QueryUserOptions.Default.WithFilter(new Dictionary<string, object>
{
{ "id", new Dictionary<string, object> { { "$in", new[]{ "john", "jack", "jassie" } } } },
}));
client.query_users({"id": {"$in": ["Jack", "Joe", "Jesie"]}})
var filters = new IFieldFilterRule[]
{
UserFilter.Id.In("user-1", "user-2", "user-3")
};
// Returns collection of IStreamUser
var users = await Client.QueryUsersAsync(filters);
client.query_users({"id": {"$in": ["Jack", "Joe", "Jesie"]}})
const response = await client.queryUsers(
{ id: { $in: ["jessica"] } },
{ last_active: -1 },
{ presence: true },
);
let controller = chatClient.userListController(
query: .init(
filter: .in(.id, values: ["john", "jack", "jessie"]),
sort: [.init(key: .lastActivityAt, isAscending: false)]
)
)
controller.synchronize { error in
if let error = error {
// handle error
print(error)
} else {
// access users
print(controller.users)
}
}
// load more if needed
controller.loadNextUsers(limit: 10) { error in
// handle error / access users
}
$response = $client->queryUsers(
[
'id' => ['$in' => ['john', 'jack', 'jessie'] ],
'last_active' => '2019-11-05T21:35:24.397995Z',
]);
final _result = client.queryUsers(
filter: Filter.in_(['john', 'jack', 'jessie']),
sort: [SortOption('last_active')],
pagination: PaginationParams(
offset: 0,
limit: 20,
),
);
Client->QueryUsers(
FFilter::In(TEXT("id"), {TEXT("john"), TEXT("jack"), TEXT("jessie")}),
{FUserSortOption{EUserSortField::LastActive}},
true, // bPresence
{{20, 0}}, // Pagination options
[](const TArray<FUserRef>& Users)
{
// Do something with Users
});
var query = QueryUserOptions.Default.WithFilter(new Dictionary<string, object>
{
{ "id", new Dictionary<string, object> { { "$in", new[]{"jessica"} } } },
});
query.Presence = true;
var resp = await userClient.QueryAsync(query);
client.query_users({"id": {"$eq": "Jessica"}}, { "last_active": -1})
var lastWeek = DateTime.Now.AddDays(-7);
var filters = new IFieldFilterRule[]
{
UserFilter.CreatedAt.GreaterThanOrEquals(lastWeek)
};
// Order results by one or multiple fields e.g
var sort = UsersSort.OrderByDescending(UserSortField.CreatedAt);
var limit = 30; // How many records per page
var offset = 0; // How many records to skip e.g. offset = 30 -> page 2, offset = 60 -> page 3, etc.
// Returns collection of IStreamUser
var users = await Client.QueryUsersAsync(filters, sort, offset, limit);
client.query_users({"id": {"$eq": "Jessica"}}, { "last_active": -1})
Another option is to query for banned
users. This can be done with the following code snippet:
val request = QueryUsersRequest(
filter = Filters.eq("banned", true),
offset = 0,
limit = 10,
)
client.queryUsers(request).enqueue { /* ... */ }
const banned = await client.queryUsers({ id: "jessica", banned: true });
$banned = $client->queryUsers(
[
'id' => 'bob-1',
'banned' => true,
]);
let controller = chatClient.userListController(
query: .init(
filter: .equal(.isBanned, to: true),
sort: [.init(key: .lastActivityAt, isAscending: false)]
)
)
controller.synchronize { error in
if let error = error {
// handle error
print(error)
} else {
// access users
print(controller.users)
}
}
FilterObject filter = Filters.eq("banned", true);
int offset = 0;
int limit = 10;
QueryUsersRequest request = new QueryUsersRequest(filter, offset, limit);
client.queryUsers(request).enqueue(result -> { /* ... */ });
final _result = client.queryUsers(
filter: Filter.and(
Filter.equal('id', 'jessie'),
Filter.equal('banned', true),
),
sort: [SortOption('last_active')],
pagination: PaginationParams(
offset: 0,
limit: 20,
),
);
Client->QueryUsers(
FFilter::And({
FFilter::Equal(TEXT("id"), TEXT("jessie")),
FFilter::Equal(TEXT("banned"), true),
}),
{FUserSortOption{EUserSortField::LastActive}},
true, // Presence
{}, // Pagination options
[](const TArray<FUserRef>& Users)
{
// Do something with Users
});
var resp = await userClient.QueryAsync(QueryUserOptions.Default.WithFilter(new Dictionary<string, object>
{
{ "id", new Dictionary<string, object> { { "$in", new[]{ "john" } } } },
{ "banned": true },
}));
client.query_users({"id": {"$eq": "Jessica"}, "banned": True})
// Returns collection of StreamUserBanInfo
var usersBanInfo = await Client.QueryBannedUsersAsync(new StreamQueryBannedUsersRequest
{
CreatedAtAfter = null, // Optional Banned after this date
CreatedAtAfterOrEqual = null, // Optional Banned after or equal this date
CreatedAtBefore = null, // Optional Banned before this date
CreatedAtBeforeOrEqual = null, // Optional Banned before or equal this date
FilterConditions = null, // Optional filter
Limit = 30,
Offset = 60,
Sort = new List<StreamSortParam> // Optional sort
{
new StreamSortParam
{
Field = "created_at",
Direction = -1,
}
},
});
foreach (var banInfo in usersBanInfo)
{
Debug.Log(banInfo.User); // Which user
Debug.Log(banInfo.Channel); // From which channel
Debug.Log(banInfo.Reason); // Reason why banned
Debug.Log(banInfo.Expires); // Optional expiry date
Debug.Log(banInfo.Shadow); // Is this a shadow ban
Debug.Log(banInfo.BannedBy); // Who created a ban
Debug.Log(banInfo.CreatedAt); // Date when banned
}
client.query_users({"id": {"$eq": "Jessica"}, "banned": true})
An object with an array of users will be returned.
Please be aware that this query will return users banned across the entire app, not at a channel level.
All filters use a Mongoose style syntax; however, we do not run MongoDB on the backend, so you can only use a subset of queries that are normally available within Mongoose. The supported queries are described below.
You can filter and sort on the custom fields you’ve set for your user, the user id, and when the user was last active.
Supported queries
The options for the queryUser
method are include_deactivated_users
, presence
, limit
, and offset
. If presence
is true
this makes sure you receive the user.presence.changed
event when a user goes online or offline.
name | type | description | default | optional |
---|---|---|---|---|
filter_conditions | objects | Conditions to use to filter the users | - | |
presence | boolean | Get updates when the user goes offline/online | true | ✓ |
sort | object or array of objects | The sorting used for the users matching the filters. Sorting is based on field and direction, and multiple sorting options can be provided. Direction can be ascending (1) or descending (-1). | [{created_at: -1}, {id: -1}] | ✓ |
limit | integer | Number of users to return | 30 | ✓ |
offset | integer | Offset for pagination | 0 | ✓ |
id_gt | string | ID-based pagination. Return IDs greater than this ID. If this is not empty, the default sort order will be [{id: -1}]. | - | ✓ |
id_gte | string | ID-based pagination. Return IDs greater than or equal to this ID. If this is not empty, the default sort order will be [{id: -1}]. | - | ✓ |
id_lt | string | ID-based pagination. Return IDs less than this ID. If this is not empty, the default sort order will be [{id: -1}]. | - | ✓ |
id_lte | string | ID-based pagination. Return IDs less than or equal to this ID. If this is not empty, the default sort order will be [{id: -1}]. | - | ✓ |
include_deactivated_users | boolean | Include deactivated users in the response | - | ✓ |
You can subscribe to presence status of at most 30 users using this method.
Note - The offset limit is set to 1000.
Filter conditions
Name | Type | Description | allowed operators |
---|---|---|---|
id | string | ID of the user | $eq, $gt, $gte, $lt, $lte, $in, $autocomplete |
role | string | role of the user | $eq, $gt, $gte, $lt, $lte, $in |
banned | boolean | users that have been banned | $eq |
shadow_banned | boolean | users that have been shadow banned | $eq |
created_at | string, must be formatted as an RFC3339 timestamp | created time of the user | $eq, $gt, $gte, $lt, $lte, $in |
updated_at | string, must be formatted as an RFC3339 timestamp | updated time of the user | $eq, $gt, $gte, $lt, $lte, $in |
last_active | string, must be formatted as an RFC3339 timestamp | time when the user was last active | $eq, $gt, $gte, $lt, $lte, $in |
teams | string | teams that the user belongs to | $eq, $contains |
name | string | name property of the user | $eq, $autocomplete |
username | string | username property of the user | $eq, $autocomplete |
Querying Using the $autocomplete Operator
You can autocomplete the results of your user query by username and/or ID.
1. By Name
If you want to return all users whose field 'name'
has a value that includes 'ro'
, you could do so with the following:
val request = QueryUsersRequest(
filter = Filters.autocomplete("name", "ro"),
offset = 0,
limit = 10,
)
client.queryUsers(request).enqueue { /* ... */ }
const response = await serverClient.queryUsers({
name: { $autocomplete: "ro" },
});
$response = $client->queryUsers(
[
'name' => ['$autocomplete' => 'ro']
]);
let controller = chatClient.userListController(
query: .init(filter: .autocomplete(.name, text: "ro"))
)
controller.synchronize { error in
if let error = error {
// handle error
print(error)
} else {
// access users
print(controller.users)
}
}
FilterObject filter = Filters.autocomplete("name", "ro");
int offset = 0;
int limit = 10;
QueryUsersRequest request = new QueryUsersRequest(filter, offset, limit);
client.queryUsers(request).enqueue(result -> { /* ... */ });
final _result = client.queryUsers(
filter: Filter.autoComplete('name', 'ro'),
);
Client->QueryUsers(
FFilter::Autocomplete(TEXT("name"), TEXT("ro")),
{}, // Sort
true, // Presence
{}, // Pagination options
[](const TArray<FUserRef>& Users)
{
// Do something with Users
});
var resp = await _userClient.QueryAsync(QueryUserOptions.Default.WithFilter(new Dictionary<string, object>
{
{ "name", new Dictionary<string, object> { { "$autocomplete", "ro" } } },
}));
client.query_users({"name": {"$autocomplete": "ro"}})
client.query_users({"name": {"$autocomplete": "ro"}})
var filters = new IFieldFilterRule[]
{
UserFilter.Name.Autocomplete("Ro")
};
// Returns collection of IStreamUser
var users = await Client.QueryUsersAsync(filters);
This would return an array of any matching users, such as:
[
{
"id": "userID",
"name": "Curiosity Rover"
},
{
"id": "userID2",
"name": "Roxy"
},
{
"id": "userID3",
"name": "Roxanne"
}
]
2. By ID
val request = QueryUsersRequest(
filter = Filters.autocomplete("id", "USER_ID"),
offset = 0,
limit = 10,
)
client.queryUsers(request).enqueue { /* ... */ }
const response = await client.queryUsers({ id: { $autocomplete: "USER_ID" } });
$response = $client->queryUsers(
[
'id' => ['$autocomplete' => 'user-id']
]);
let controller = chatClient.userListController(
query: .init(filter: .autocomplete(.id, text: "ro"))
)
controller.synchronize { error in
if let error = error {
// handle error
print(error)
} else {
// access users
print(controller.users)
}
}
FilterObject filter = Filters.autocomplete("id", "USER_ID");
int offset = 0;
int limit = 10;
QueryUsersRequest request = new QueryUsersRequest(filter, offset, limit);
client.queryUsers(request).enqueue(result -> { /* ... */ });
final _result = client.queryUsers(
filter: Filter.autocomplete('id', 'userid'),
);
Client->QueryUsers(
FFilter::Autocomplete(TEXT("id"), TEXT("userid")),
{}, // Sort
true, // Presence
{}, // Pagination options
[](const TArray<FUserRef>& Users)
{
// Do something with Users
});
var resp = await _userClient.QueryAsync(QueryUserOptions.Default.WithFilter(new Dictionary<string, object>
{
{ "name", new Dictionary<string, object> { { "$autocomplete", userId } } },
}));
client.query_users({"name": {"$autocomplete": user_id}})
client.query_users({"name": {"$autocomplete": user_id}})
var filters = new IFieldFilterRule[]
{
// Return all users with Id starting with `Ro` like: Roxy, Roxanne, Rover
UserFilter.Name.Autocomplete("Ro")
};
// Returns collection of IStreamUser
var users = await Client.QueryUsersAsync(filters);