Skip to main content

Friend Management

This document guides developers on using RC's Android IMLib SDK to implement friend-related features including adding friends, removing friends, viewing friend lists, and managing friend relationships.

tip

This feature is supported starting from version 5.12.0.

Enabling the Service

Before using this feature, you must enable the profile hosting service by submitting a ticket.

Friend Event Listening

To receive real-time notifications for friend operations (add/delete), friend request status changes, friend list clearing, and multi-device synchronization of friend information changes, you need to set up a friend event listener [FriendEventListener] after initializing the IMLib SDK but before establishing the connection.

Call setFriendEventListener to set the friend event listener. Pass null to stop receiving friend events.

tip

In User Profile Hosting service, SDK notifications for friend operations count as status notifications. The server will synchronize status with the SDK regardless of whether your app implements event listeners, ensuring up-to-date friend relationship status. These notifications are included in message distribution and downstream data statistics.

Sample Code

FriendEventListener friendEventListener = new FriendEventListener() {
@Override
public void onFriendAdd(DirectionType directionType, String userId, String name, String portraitUri, long operationTime) {
// Friend added callback
}

@Override
public void onFriendDelete(DirectionType directionType, List<String> userIds, long operationTime) {
// Friend removed callback
}

@Override
public void onFriendApplicationStatusChanged(String userId, FriendApplicationType applicationType, FriendApplicationStatus status, DirectionType directionType, long operationTime, String extra) {
// Friend request status change callback
}

@Override
public void onFriendCleared(long operationTime) {
// Friend list cleared callback (Note: This operation can only be initiated by the server)
}

@Override
public void onFriendInfoChangedSync(String userId, String remark, Map<String, String> extProfile, long operationTime) {
// Multi-device synchronization callback for friend information changes
}
};
RongCoreClient.getInstance().setFriendEventListener(friendEventListener);

Friend Online Status and Profile Changes

The IMLib SDK automatically handles online status and profile changes between friends.
To receive change notifications, call addSubscribeEventListener to set up a change listener after SDK initialization but before connection.

Handle different business logic based on SubscribeType:

  • FRIEND_ONLINE_STATUS(3) indicates friend online status
  • FRIEND_USER_PROFILE(4) indicates friend profile information
tip

You must enable "Client-side Friend Profile Change Notifications" and "Client-side Friend Online Status Change Notifications" in the developer console to receive real-time notifications about online status and profile changes between friends. These notifications are included in one-to-one chat message distribution and downstream data statistics.

Sample Code

RongCoreClient.getInstance().addSubscribeEventListener(new OnSubscribeEventListener() {
/**
* @param subscribeEvents List of subscription events containing all changed events.
* When a subscribed user's status changes, SubscribeEvent.operationType has no value.
* No notification is sent for expired subscriptions - developers must track expiration times.
* Note: Check SubscribeInfoEvent's SubscribeType - FRIEND_ONLINE_STATUS for friend online status, FRIEND_USER_PROFILE for friend profiles
*/
@Override
public void onEventChange(List<SubscribeInfoEvent> subscribeEvents) {

}

/**
* Marks subscription data synchronization as complete. Called after subscription data is successfully synced to the device/system for subsequent processing.
* Note: Check SubscribeType - FRIEND_ONLINE_STATUS for friend online status, FRIEND_USER_PROFILE for friend profiles
*
* @param type Synchronization completion type. Determine specific business completion by type.
* @since 5.10.0
*/
@Override
public void onSubscriptionSyncCompleted(SubscribeEvent.SubscribeType type) {

}

});

Friend Operations

Adding Friends

Call addFriend to add a specified user as a friend by their userId. Use the extra parameter to send additional information with the friend request. Obtain userIds using RC's User Search feature.

tip

A user can add up to 3000 friends.

Sample Code

// Target user ID to add as friend
String userId = "user1";
// Add as mutual friend
DirectionType directionType = DirectionType.Both;
// Additional request message (max 128 characters)
String extra = "Friend request";
RongCoreClient.getInstance().addFriend(userId, directionType, extra, new IRongCoreCallback.ResultCallback<IRongCoreEnum.CoreErrorCode>() {
@Override
public void onSuccess(IRongCoreEnum.CoreErrorCode processCode) {
// Friend request succeeded
}

@Override
public void onError(IRongCoreEnum.CoreErrorCode e) {
// Friend request failed
}
});

Setting Friend Addition Permissions

Use setFriendAddPermission to configure the current user's friend addition permissions. If not set, the AppKey's default permission applies.

Permission Notes

  • Default AppKey permission is Require user consent for friend additions.
  • User-level permissions override AppKey defaults. If unset, AppKey permissions apply.

FriendAddPermission Enum Values

Enum ValueDescription
FreeAnyone can add directly
NeedVerifyRequire user consent for friend additions
NoOneAllowedNo one can add as friend

Sample Code

// Set current permission to NeedVerify
FriendAddPermission permission = FriendAddPermission.NeedVerify;
RongCoreClient.getInstance().setFriendAddPermission(permission, new IRongCoreCallback.OperationCallback() {
@Override
public void onSuccess() {
// Permission update succeeded
}

### Get Friend Permission

Use `getFriendAddPermission` to retrieve the current user's friend request permission settings.

#### Sample Code
```java
RongCoreClient.getInstance().getFriendAddPermission(new IRongCoreCallback.ResultCallback<FriendAddPermission>() {
@Override
public void onSuccess(FriendAddPermission permission) {
// Retrieved friend permission successfully
}

@Override
public void onError(IRongCoreEnum.CoreErrorCode e) {
// Failed to retrieve friend permission
}
});

Different permission settings trigger these workflows:

Scenario 1: Adding friends without approval

  1. Users A and B call setFriendListener to set up friend event listeners.
  2. User B sets friend permission to "Anyone can add directly" (Free) via setFriendAddPermission (see [FriendAddPermission]).
  3. User A calls addFriend to request adding B as friend. The callback returns onSuccess with IRongCoreEnum.CoreErrorCode.SUCCESS(0), indicating direct friend addition. Both users receive the friend add callback [onFriendAdd].

Scenario 2: Adding friends requires approval

  1. Users A and B call setFriendListener to set up friend event listeners.
  2. User B sets friend permission to "Require user consent" (NeedVerify) via setFriendAddPermission (see [FriendAddPermission]).
  3. User A calls addFriend to request adding B as friend. The callback returns onSuccess with IRongCoreEnum.CoreErrorCode.RC_FRIEND_NEED_ACCEPT(25461), indicating pending approval. Both users receive the friend request status callback [onFriendApplicationStatusChanged].
  4. User B receives [onFriendApplicationStatusChanged] callback with [FriendApplicationStatus] as UnHandled, then chooses to accept or reject:
    • User B calls acceptFriendApplication to accept, triggering [onFriendAdd] callback for both users.
    • User B calls refuseFriendApplication to reject, triggering [onFriendApplicationStatusChanged] callback with [FriendApplicationStatus] as Refused.

Remove Friends

Use deleteFriends to remove friend relationships in bulk. Successful removal triggers [onFriendDelete] callback for both parties.

Maximum 100 friends per operation.

Sample Code

// Friend user ID list
List<String> userIds = new ArrayList<>();
userIds.add("user1");
userIds.add("user2");
userIds.add("user3");
// Remove bidirectional friends
DirectionType directionType = DirectionType.Both;
RongCoreClient.getInstance().deleteFriends(userIds, directionType, new IRongCoreCallback.OperationCallback() {
@Override
public void onSuccess() {
// Friends removed successfully
}

@Override
public void onError(IRongCoreEnum.CoreErrorCode e) {
// Failed to remove friends
}
});

Check Friend Status

Use checkFriends to verify friend relationships (currently supports bidirectional checks only).

tip

Maximum 20 users per check.

Sample Code

// Friend user ID list
List<String> userIds = new ArrayList<>();
userIds.add("user1");
userIds.add("user2");
userIds.add("user3");
// Check bidirectional friends
DirectionType directionType = DirectionType.Both;
RongCoreClient.getInstance().checkFriends(userIds, directionType, new IRongCoreCallback.ResultCallback<List<FriendRelationInfo>>() {
@Override
public void onSuccess(List<FriendRelationInfo> friendRelationInfos) {
// Check completed successfully
}

@Override
public void onError(IRongCoreEnum.CoreErrorCode e) {
// Check failed
}
});

Friend Request Operations

Paginated Friend Request List

Use getFriendApplications to view all sent/received friend request records.

  • This API doesn't return total request count.
  • Friend requests expire after 7 days. Requests older than 7 days require new submissions.
tip

Pagination notes:

  1. For initial fetch, leave [PagingQueryOption]'s pageToken unset (null/"" equivalent).
  2. Subsequent pages require the pageToken from [PagingQueryResult]:
    • If non-empty, use it to fetch next page until empty (indicating completion).
    • If empty, no more pages exist. Passing "" fetches first page again.

Sample Code

{
// ...
// Pagination parameter (null and "" are equivalent)
String pageToken = "";
getFriendApplications(pageToken);
// ...
}

public void getFriendApplications(String pageToken) {
// Pagination parameters
PagingQueryOption option = new PagingQueryOption();
// Page size (1-100)
option.setCount(20);
// Pagination token
option.setPageToken(pageToken);
// Sort order: true=ascending, false=descending
option.setOrder(false);
// Query both sent and received requests
FriendApplicationType[] types = new FriendApplicationType[]{FriendApplicationType.Sent, FriendApplicationType.Received};
// Query all statuses
FriendApplicationStatus[] status = new FriendApplicationStatus[]{FriendApplicationStatus.UnHandled, FriendApplicationStatus.Accepted, FriendApplicationStatus.Refused};
RongCoreClient.getInstance().getFriendApplications(option, types, status, new IRongCoreCallback.PageResultCallback<FriendApplicationInfo>() {
@Override
public void onSuccess(PagingQueryResult<FriendApplicationInfo> result) {
if (!TextUtils.isEmpty(result.getPageToken())) {
// Fetch next page using returned token
getFriendApplications(result.getPageToken());
} else {
// Pagination complete
}
}

### Accept Friend Request

After receiving a friend request, call `acceptFriendApplication` to accept it. Upon successful callback, the friend relationship is established, and both parties will trigger the [onFriendAdd] callback.

The friend request status [FriendApplicationStatus] in the application list will change to `Accepted`.

#### Sample Code
```java
// Friend user ID
String userId = "user1";
RongCoreClient.getInstance().acceptFriendApplication(userId, new IRongCoreCallback.OperationCallback() {
@Override
public void onSuccess() {
// Successfully accepted friend request
}

@Override
public void onError(IRongCoreEnum.CoreErrorCode e) {
// Failed to accept friend request
}
});

Reject Friend Request

Upon receiving a friend request, users can reject it by calling refuseFriendApplication.

After successful rejection, both parties will trigger the [onFriendApplicationStatusChanged] callback, with the friend request status [FriendApplicationStatus] set to Refused.

Sample Code

// Friend user ID
String userId = "user1";
RongCoreClient.getInstance().refuseFriendApplication(userId, new IRongCoreCallback.OperationCallback() {
@Override
public void onSuccess() {
// Successfully rejected friend request
}

@Override
public void onError(IRongCoreEnum.CoreErrorCode e) {
// Failed to reject friend request
}
});

Managing Friend Information

Get Friend List

Use getFriends to retrieve the current user's friend list.

Sample Code

// Query bidirectional friend list
QueryFriendsDirectionType type = QueryFriendsDirectionType.Both;
RongCoreClient.getInstance().getFriends(type, new IRongCoreCallback.ResultCallback<List<FriendInfo>>() {
@Override
public void onSuccess(List<FriendInfo> friendInfos) {
// Successfully retrieved friend list
}

@Override
public void onError(IRongCoreEnum.CoreErrorCode e) {
// Failed to retrieve friend list
}
});

Set Friend Information

Use setFriendInfo to configure a friend's remark name and extended information.

tip
  • Extended information keys must first be configured in the RC Console [Friend Custom Attributes] before use, otherwise the operation will fail. A maximum of 10 extended keys can be set.
  • After successful modification, other devices logged in by the same user will receive the multi-device sync callback [onFriendInfoChangedSync].
  • By default, modified information isn't subject to moderation. To enable moderation, go to [Console] > App Configuration > Security & Moderation > IM & RTC Moderation > IM Information Hosting Configuration, then enable and configure the content requiring moderation.

Sample Code

// Friend user ID
String userId = "user1";
// Friend remark name (max 64 characters). Leave empty to clear existing remark
String remark = "user1's remark name";
// Extended information (max 10 key-value pairs by default)
Map<String, String> extProfile = new HashMap<>();
extProfile.put("ext_key_1", "ext_value_1");
extProfile.put("ext_key_2", "ext_value_2");
RongCoreClient.getInstance().setFriendInfo(userId, remark, extProfile, new IRongCoreCallback.OperationCallback() {
@Override
public void onSuccess() {
// Successfully set friend information
}

@Override
public void onError(IRongCoreEnum.CoreErrorCode e) {
// Failed to set friend information
}
});

Get Friend Information by User ID

Use getFriendsInfo to retrieve friend information by user ID.
This interface supports batch queries—you can pass up to 100 user IDs simultaneously.

Sample Code

// List of friend user IDs
List<String> userIds = new ArrayList<>();
userIds.add("user1");
userIds.add("user2");
userIds.add("user3");
RongCoreClient.getInstance().getFriendsInfo(userIds, new IRongCoreCallback.ResultCallback<List<FriendInfo>>() {
@Override
public void onSuccess(List<FriendInfo> friendInfos) {
// Successfully retrieved friend information
}

@Override
public void onError(IRongCoreEnum.CoreErrorCode e) {
// Failed to retrieve friend information
}
});

Search Friends by Nickname

Use searchFriendsInfo to search for friends by nickname.

The search first checks friend remark names (remark), then friend names (name). Results are returned when either field matches.

Sample Code

// Nickname keyword (required, max 64 characters)
String name = "name";
RongCoreClient.getInstance().searchFriendsInfo(name, new IRongCoreCallback.ResultCallback<List<FriendInfo>>() {
@Override
public void onSuccess(List<FriendInfo> friendInfos) {
// Successfully searched friend list
}

@Override
public void onError(IRongCoreEnum.CoreErrorCode e) {
// Failed to search friend list
}
});
AppKey PermissionUser PermissionResult
Free, NeedVerify, NoOneAllowedNot setFollows AppKey permission settings
Free, NeedVerify, NoOneAllowedSet to (Free, NeedVerify, NoOneAllowed)Follows user permission settings