> For the complete documentation index, see [llms.txt](https://docs.coherence.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.coherence.io/hosting/coherence-cloud/game-services/friends.md).

# Friends

Mirror platform friend lists and share online presence

The **Friends** service mirrors the friend list a player keeps on their platform (Game Center, PlayStation Network, Nintendo, Xbox, Steam, Epic, or a source your own game provides) into the coherence Cloud. Friends can see whether each other is online, what they are up to, and which [Lobbies](/hosting/coherence-cloud/game-services/lobbies.md) they are in.

You can access the [FriendsService](https://unityapi.coherence.io/docs/v2.3.0/api/Coherence.Cloud.FriendsService.html) via the **Friends** property of a Player Account's **Services**.

{% hint style="info" %}
You must be logged into the coherence Cloud to use this service. Read more about authentication on the [Player Accounts](/hosting/coherence-cloud/authentication-service-player-accounts.md) page.
{% endhint %}

{% hint style="warning" %}
Guest and username/password accounts can't have friends.
{% endhint %}

## Syncing friends

coherence doesn't read friend lists from platforms. Your game reads them, and uploads the ids with **SyncFriendsAsync**, naming the platform they come from: `"gamecenter"`, `"psn"`, `"nintendo"`, `"xbox"`, `"steam"`, `"epic"` or `"custom"`.

Call it after logging in, and again whenever the platform reports that the friend list changed. Each sync replaces the friends previously synced from the same platform, without affecting other platforms. Syncing an empty list removes every friend synced from that platform.

Friendships are mutual: a player shows up in **Friends** only once both players have synced each other. Ids of players who have never logged in to your project are discarded.

```csharp
using Coherence.Cloud;
using UnityEngine;

public class FriendsSyncExample : MonoBehaviour
{
    async void Start()
    {
        // Wait until a player account has logged in to coherence Cloud.
        // The CoherenceCloudLogin component can be used for this.
        PlayerAccount playerAccount = await PlayerAccount.GetMainAsync();
        var friends = playerAccount.Services.Friends;

        friends.OnFriendAdded += friend => Debug.Log($"{friend.DisplayName} is now a friend.");
        friends.OnFriendRemoved += friend => Debug.Log($"{friend.DisplayName} is no longer a friend.");

        // Read the player's friend list from the platform yourself.
        // Here we're using placeholder Steam ids.
        var steamFriendIds = new[] { "76561197960287930", "76561197960287931" };

        await friends.SyncFriendsAsync("steam", steamFriendIds)
            .OnFail(Debug.LogWarning)
            .OnSuccess(result => Debug.Log($"{result.Resolved} of them play this game."));

        // A friend shows up only once both players have synced each other.
        foreach (var friend in friends.Friends)
        {
            Debug.Log(friend.DisplayName);
        }
    }
}
```

Logging in doesn't fetch friends. Use **RefreshFriendsAsync** to read the list without syncing. After the first sync or refresh, coherence keeps **Friends** up to date while the player is connected, and raises **OnFriendAdded**, **OnFriendRemoved** and **OnFriendPresenceChanged** as changes come in.

{% hint style="info" %}
coherence Cloud currently accepts up to 2000 friend ids per sync, each up to 64 characters long, and up to 10 syncs a minute.
{% endhint %}

## Online presence

Each [Friend](https://unityapi.coherence.io/docs/v2.3.0/api/Coherence.Cloud.Friend.html) reports:

* **IsOnline** and **LastOnlineAt**: whether they are playing right now, and when they were last seen playing.
* **Presence**: a custom status message they set with **SetPresenceAsync**, such as "In the main menu". Pass `null` or an empty string to clear it.
* **LobbyIds**: the Lobbies they are in, the most recently joined first. Pass one to **JoinLobbyAsync** to join them.

**OnFriendPresenceChanged** is raised whenever a friend comes online, goes offline, or changes their presence or Lobbies.

```csharp
using Coherence.Cloud;
using UnityEngine;

public class FriendsPresenceExample : MonoBehaviour
{
    async void Start()
    {
        // Wait until a player account has logged in to coherence Cloud.
        // The CoherenceCloudLogin component can be used for this.
        PlayerAccount playerAccount = await PlayerAccount.GetMainAsync();
        var friends = playerAccount.Services.Friends;

        friends.OnFriendPresenceChanged += friend =>
        {
            if (!friend.IsOnline)
            {
                Debug.Log($"{friend.DisplayName} left. Last seen {friend.LastOnlineAt}.");
                return;
            }

            Debug.Log($"{friend.DisplayName} is playing: {friend.Presence}");
        };

        await friends.RefreshFriendsAsync();
        await friends.SetPresenceAsync("In the main menu");

        // Join the lobby of the first friend that is in one.
        foreach (var friend in friends.Friends)
        {
            if (friend.LobbyIds.Count == 0)
            {
                continue;
            }

            await playerAccount.Services.Lobbies.JoinLobbyAsync(friend.LobbyIds[0]);
            break;
        }
    }
}
```

A Lobby created with **CreateLobbyOptions.HideFromPresence** doesn't show up in its members' **LobbyIds**.

To hide from friends without logging out, use **SetAppearOfflineAsync**. While hidden, friends see the player as offline, with no presence and no Lobbies. Unlike presence, this setting is kept on the player account, so it stays applied across reconnects and logins until it's set back to `false`.

{% hint style="info" %}
coherence Cloud currently accepts presence messages of up to 512 bytes of UTF-8 text, and up to 120 presence updates a minute, counting **SetAppearOfflineAsync**.
{% endhint %}
