Friend management
This guide explains how to use the Nexconn SDK to add friends, remove friends, view friend lists, and manage friend relationships.
Listen for friend events
To receive real-time notifications about friend additions, deletions, application status changes, friend list clearance, and friend info updates across devices, register a UserHandler after SDK initialization but before connecting.
- Kotlin
- Java
NCEngine.addUserHandler("FRIEND_HANDLER", object : UserHandler {
override fun onFriendAdd(info: FriendAddEvent) {
println("Friend added: ${info.userId}")
}
override fun onFriendDelete(info: FriendDeleteEvent) {
println("Friends deleted: ${info.userIds}")
}
override fun onFriendApplicationStatusChanged(event: FriendApplicationStatusChangedEvent) {
println("Friend application status changed for: ${event.userId}")
}
override fun onFriendCleared(event: FriendClearedEvent) {
// Only triggered by server-side operations
}
override fun onFriendInfoChangedSync(info: FriendInfoChangedSyncEvent) {
println("Friend info changed: ${info.userId}")
}
})
NCEngine.addUserHandler("FRIEND_HANDLER", new UserHandler() {
@Override
public void onFriendAdd(@NonNull FriendAddEvent info) {
}
@Override
public void onFriendDelete(@NonNull FriendDeleteEvent info) {
}
@Override
public void onFriendApplicationStatusChanged(@NonNull FriendApplicationStatusChangedEvent event) {
}
@Override
public void onFriendCleared(@NonNull FriendClearedEvent event) {
// Only triggered by server-side operations
}
@Override
public void onFriendInfoChangedSync(@NonNull FriendInfoChangedSyncEvent info) {
}
});
Friend operations performed through the friend management APIs trigger SDK notification callbacks as a form of state synchronization. Regardless of whether you implement event listeners, the server synchronizes state to the SDK to keep the local friend relationship data up to date. These notifications count toward message distribution and downstream data statistics.
Friend presence and profile changes
The Nexconn SDK automatically handles friend presence and user profile changes. To receive change event notifications, call NCEngine.addUserHandler after SDK initialization but before connecting.
Handle events based on the SubscribeType:
FRIEND_ONLINE_STATUS— Friend presence changesFRIEND_USER_PROFILE— Friend profile changes
Enable "Client friend profile change notification" and "Client friend online status change notification" in the developer Console before using this feature. These notifications count toward direct message distribution and downstream data statistics.
Example
- Kotlin
- Java
NCEngine.addUserHandler("FRIEND_STATUS", object : UserHandler {
override fun onSubscriptionChanged(event: SubscriptionChangedEvent) {
event.events.forEach { info ->
println("User ${info.userId} status changed")
}
}
override fun onSubscriptionSyncCompleted(event: SubscriptionSyncCompletedEvent) {
println("Subscription sync completed: ${event.subscribeType}")
}
})
NCEngine.addUserHandler("FRIEND_STATUS", new UserHandler() {
@Override
public void onSubscriptionChanged(@NonNull SubscriptionChangedEvent event) {
for (SubscribeStatusInfo info : event.getEvents()) {
Log.d("Friend", "User " + info.getUserId() + " status changed");
}
}
@Override
public void onSubscriptionSyncCompleted(@NonNull SubscriptionSyncCompletedEvent event) {
Log.d("Friend", "Subscription sync completed: " + event.getSubscribeType());
}
});
Friend operations
Add a friend
Call NCEngine.userModule.addFriend to send a friend request to a user by userId. Use the extra field to attach additional information to the friend request.
You can obtain a user's userId using the [user search] feature.
Each user can have a maximum of 3,000 friends.
AddFriendParams
| Parameter | Type | Description |
|---|---|---|
| userId | String | The user ID to add as a friend (constructor parameter) |
| extra | String? | Additional information attached to the friend request |
Example
- Kotlin
- Java
val params = AddFriendParams("user1").apply {
extra = "Please add me as a friend"
}
NCEngine.userModule.addFriend(params) { resultCode, error ->
if (error == null) {
// Friend request sent successfully
} else {
// Friend request failed
}
}
AddFriendParams params = new AddFriendParams("user1");
params.setExtra("Please add me as a friend");
NCEngine.userModule.addFriend(params, (resultCode, error) -> {
if (error == null) {
// Friend request sent successfully
} else {
// Friend request failed
}
return null;
});
Set friend request permissions
Call NCEngine.userModule.setFriendAddPermission to set the current user's friend request permissions. If not set, the app-level default permission applies.
Permission behavior
- The default app-level permission is Require approval.
- User-level permission overrides the app-level setting. If the user has not set a permission, the app-level setting applies.
FriendAddPermission enum
| Value | Description |
|---|---|
| FREE | Anyone can add as a friend directly |
| NEED_VERIFY | Require the user's approval |
| NO_ONE_ALLOWED | No one can add as a friend |
Example
- Kotlin
- Java
NCEngine.userModule.setFriendAddPermission(FriendAddPermission.NEED_VERIFY) { error ->
if (error == null) {
// Permission set successfully
}
}
NCEngine.userModule.setFriendAddPermission(FriendAddPermission.NEED_VERIFY, error -> {
if (error == null) {
// Permission set successfully
}
return null;
});
Get friend request permissions
Call NCEngine.userModule.getFriendAddPermission to retrieve the current user's friend request permission.
Example
- Kotlin
- Java
NCEngine.userModule.getFriendAddPermission { permission, error ->
if (error == null && permission != null) {
println("Current permission: $permission")
}
}
NCEngine.userModule.getFriendAddPermission((permission, error) -> {
if (error == null && permission != null) {
Log.d("Friend", "Current permission: " + permission);
}
return null;
});
Permission scenarios
Scenario 1: No approval required
- Users A and B register friend event listeners.
- User B calls
setFriendAddPermissionwithFriendAddPermission.FREE. - User A calls
addFriendto add B. The callback succeeds withresultCode0, meaning the friendship is established immediately. Both A and B receive the friend added callback.
Scenario 2: Approval required
- Users A and B register friend event listeners.
- User B calls
setFriendAddPermissionwithFriendAddPermission.NEED_VERIFY. - User A calls
addFriendto add B. The callback succeeds withresultCode25461, meaning the request is pending B's approval. Both A and B receive the friend application status callback. - User B receives the friend request callback with status
FriendApplicationStatus.UN_HANDLEDand can accept or reject:- Call
acceptFriendApplicationto accept. Both parties receive the friend added callback. - Call
refuseFriendApplicationto reject. Both parties receive the friend application status callback withFriendApplicationStatus.REFUSED.
- Call
Remove friends
Call NCEngine.userModule.deleteFriends to remove friends in bulk. After removal, both parties receive the friend deleted callback.
Each call supports removing up to 100 friends.
Example
- Kotlin
- Java
NCEngine.userModule.deleteFriends(listOf("user1", "user2", "user3")) { error ->
if (error == null) {
// Friends removed successfully
}
}
NCEngine.userModule.deleteFriends(Arrays.asList("user1", "user2", "user3"), error -> {
if (error == null) {
// Friends removed successfully
}
return null;
});
Check friendships
Call NCEngine.userModule.checkFriends to verify friend relationships. Currently supports bidirectional friend checks only.
You can check up to 20 users at a time.
Example
- Kotlin
- Java
NCEngine.userModule.checkFriends(listOf("user1", "user2", "user3")) { relations, error ->
if (error == null && relations != null) {
relations.forEach { relation ->
println("User ${relation.userId}: ${relation.relationType}")
}
}
}
NCEngine.userModule.checkFriends(Arrays.asList("user1", "user2", "user3"), (relations, error) -> {
if (error == null && relations != null) {
for (FriendRelation relation : relations) {
Log.d("Friend", "User " + relation.getUserId() + ": " + relation.getRelationType());
}
}
return null;
});
Friend requests
List friend requests (paginated)
Call NCEngine.userModule.createFriendApplicationsQuery to create a paginated query for all sent and received friend requests.
- Friend requests are valid for 7 days. The server stores request data for up to 7 days. After expiration, a new request must be sent.
FriendApplicationsQueryParams
| Parameter | Type | Description |
|---|---|---|
| pageSize | Int | Number of items per page. Default: 20. |
| isAscending | Boolean | Sort order. true: ascending; false: descending (default). |
Example
- Kotlin
- Java
val params = FriendApplicationsQueryParams().apply {
pageSize = 20
isAscending = false
}
val query = NCEngine.userModule.createFriendApplicationsQuery(params)
query.loadNextPage { result, error ->
if (error == null && result != null) {
result.data.forEach { app ->
println("User ${app.userId}: ${app.applicationStatus}")
}
if (result.hasMore) {
query.loadNextPage { nextResult, nextError ->
// Load next page
}
}
}
}
FriendApplicationsQueryParams params = new FriendApplicationsQueryParams();
params.setPageSize(20);
params.setIsAscending(false);
FriendApplicationsQuery query = NCEngine.userModule.createFriendApplicationsQuery(params);
query.loadNextPage((result, error) -> {
if (error == null && result != null) {
for (FriendApplicationDetail app : result.getData()) {
Log.d("Friend", "User " + app.getUserId() + ": " + app.getApplicationStatus());
}
if (result.getHasMore()) {
query.loadNextPage((nextResult, nextError) -> {
// Load next page
return null;
});
}
}
return null;
});
Accept a friend request
Call NCEngine.userModule.acceptFriendApplication to accept a friend request. On success, the friendship is established and both parties receive the friend added callback.
The friend request status changes to FriendApplicationStatus.ACCEPTED.
Example
- Kotlin
- Java
NCEngine.userModule.acceptFriendApplication("user1") { error ->
if (error == null) {
// Friend request accepted
}
}
NCEngine.userModule.acceptFriendApplication("user1", error -> {
if (error == null) {
// Friend request accepted
}
return null;
});
Reject a friend request
Call NCEngine.userModule.refuseFriendApplication to reject a friend request.
On rejection, both parties receive the friend application status callback with FriendApplicationStatus.REFUSED.
Example
- Kotlin
- Java
NCEngine.userModule.refuseFriendApplication("user1") { error ->
if (error == null) {
// Friend request rejected
}
}
NCEngine.userModule.refuseFriendApplication("user1", error -> {
if (error == null) {
// Friend request rejected
}
return null;
});
Friend info
Get friend list
Call NCEngine.userModule.getFriends to retrieve the current user's friend list.
Example
- Kotlin
- Java
NCEngine.userModule.getFriends { friends, error ->
if (error == null && friends != null) {
friends.forEach { friend ->
println("${friend.userId}: ${friend.name}")
}
}
}
NCEngine.userModule.getFriends((friends, error) -> {
if (error == null && friends != null) {
for (FriendDetail friend : friends) {
Log.d("Friend", friend.getUserId() + ": " + friend.getName());
}
}
return null;
});
Set friend info
Call NCEngine.userModule.setFriendInfo to set a friend's remark name and extended profile.
- Extended profile keys must be configured in the Console under Friend custom attributes before use. Unregistered keys return an error. You can set up to 10 extended profile keys.
- After updating friend info, other devices logged in with the same account receive a friend info change callback.
SetFriendInfoParams
| Parameter | Type | Description |
|---|---|---|
| userId | String | The friend's user ID (constructor parameter) |
| remark | String? | Friend remark name. Max 64 characters. Pass empty or omit to clear. |
| extProfile | Map<String, String>? | Extended profile data. Up to 10 entries by default. |
Example
- Kotlin
- Java
val params = SetFriendInfoParams("user1").apply {
remark = "My nickname for user1"
extProfile = mapOf("ext_key_1" to "ext_value_1", "ext_key_2" to "ext_value_2")
}
NCEngine.userModule.setFriendInfo(params) { errorKeys, error ->
if (error == null) {
// Friend info updated successfully
} else {
// Update failed; errorKeys contains the keys that failed
}
}
SetFriendInfoParams params = new SetFriendInfoParams("user1");
params.setRemark("My nickname for user1");
Map<String, String> extProfile = new HashMap<>();
extProfile.put("ext_key_1", "ext_value_1");
extProfile.put("ext_key_2", "ext_value_2");
params.setExtProfile(extProfile);
NCEngine.userModule.setFriendInfo(params, (errorKeys, error) -> {
if (error == null) {
// Friend info updated successfully
} else {
// Update failed
}
return null;
});
Get friend info by user ID
Call NCEngine.userModule.getFriendsInfo to retrieve friend information by user ID. Supports batch retrieval of up to 100 users.
Example
- Kotlin
- Java
NCEngine.userModule.getFriendsInfo(listOf("user1", "user2", "user3")) { friendInfos, error ->
if (error == null && friendInfos != null) {
friendInfos.forEach { friend ->
println("${friend.userId}: ${friend.name}, Remark: ${friend.remark}")
}
}
}
NCEngine.userModule.getFriendsInfo(Arrays.asList("user1", "user2", "user3"), (friendInfos, error) -> {
if (error == null && friendInfos != null) {
for (FriendDetail friend : friendInfos) {
Log.d("Friend", friend.getUserId() + ": " + friend.getName() + ", Remark: " + friend.getRemark());
}
}
return null;
});
Search friends by name
Call NCEngine.userModule.searchFriendsInfo to search for friends by name.
The search checks the friend remark name (remark) first, then the friend name (name). If either field matches, the result is returned.
Example
- Kotlin
- Java
NCEngine.userModule.searchFriendsInfo("name") { friendInfos, error ->
if (error == null && friendInfos != null) {
friendInfos.forEach { friend ->
println("${friend.userId}: ${friend.name}")
}
}
}
NCEngine.userModule.searchFriendsInfo("name", (friendInfos, error) -> {
if (error == null && friendInfos != null) {
for (FriendDetail friend : friendInfos) {
Log.d("Friend", friend.getUserId() + ": " + friend.getName());
}
}
return null;
});
| App-level permission | User-level permission | Result |
|---|---|---|
FREE, NEED_VERIFY, NO_ONE_ALLOWED | Not set | App-level permission applies |
FREE, NEED_VERIFY, NO_ONE_ALLOWED | Set to FREE, NEED_VERIFY, or NO_ONE_ALLOWED | User-level permission applies |