Play With Friends
Updated: May 14, 2026
Copy for LLM
Play With Friends lets players
This guide covers what the Play With Friends feature is, how to use the SDK to retrieve friend data, how to display friends in your game, permission requirements, privacy considerations, and best practices.
What Is Play With Friends?
Play With Friends is not a single button or UI element -- it is a capability provided by the Instant Games SDK that lets your game identify which of the current player’s Facebook friends have also played your game. With this information, you can:
- Show a list of friends who play the game
- Display friend scores alongside the player’s own score
- Build friend-based leaderboards
- Enable direct challenges between friends
- Show social proof (“5 of your friends play this game”)
- Create cooperative features like teams or gifting
From the player’s perspective, the experience feels seamless: they open your game, and they can immediately see their friends who also play, compare scores, send challenges, and interact socially -- all without leaving the game.
Getting Connected Players
The primary API for retrieving a player’s friends who also play your game is
FBInstant.player.getConnectedPlayersAsync(). This method returns a list of players who:- Are Facebook friends of the current player
- Have also played your game
- Have granted the necessary permissions
Basic Usage
async function loadFriends() { try { const connectedPlayers = await FBInstant.player.getConnectedPlayersAsync(); connectedPlayers.forEach(player => { console.log('Friend ID:', player.getID()); console.log('Friend Name:', player.getName()); console.log('Friend Photo:', player.getPhoto()); }); return connectedPlayers; } catch (error) { console.error('Failed to load connected players:', error); return []; } }
ConnectedPlayer Object
Each player returned by
getConnectedPlayersAsync() is a ConnectedPlayer object with the following methods:| Method | Return Type | Description |
|---|---|---|
getID() | string | A unique identifier for the player, scoped to your game. This ID is consistent across sessions and can be used to store and retrieve player-specific data on your backend. |
getName() | string | The player’s display name. This is the name they use on Facebook. |
getPhoto() | string | A URL to the player’s profile photo. Use this to display avatars in your game UI. |
Example: Building a Friends List
async function renderFriendsList() { const friends = await FBInstant.player.getConnectedPlayersAsync(); if (friends.length === 0) { showMessage('Invite your friends to play!'); return; } const friendsContainer = document.getElementById('friends-list'); friendsContainer.innerHTML = ''; friends.forEach(friend => { const friendElement = document.createElement('div'); friendElement.className = 'friend-item'; friendElement.innerHTML = ` <img src="${friend.getPhoto()}" alt="${friend.getName()}" class="friend-avatar" /> <span class="friend-name">${friend.getName()}</span> `; friendsContainer.appendChild(friendElement); }); showMessage(`${friends.length} friend(s) also play this game!`); }
Permission Requirements
The user_friends Permission
To retrieve connected players, your game relies on the
user_friends permission. This permission is part of the standard Instant Games permission set and is typically granted when a player first interacts with your game through the Facebook platform.Key points about the
user_friends permission:- Automatic for Instant Games: In most cases, Instant Games receive the
user_friendspermission as part of the standard login flow. You do not need to explicitly request it in a separate permission dialog. - Player consent: Players are informed about the data your game accesses when they first open it. They can revoke permissions at any time through their Facebook privacy settings.
- Only mutual players: The
user_friendspermission only returns friends who have also played your game. You cannot see a player’s full friend list -- only friends who have both played the game and granted permission.
What If No Friends Are Returned?
If
getConnectedPlayersAsync() returns an empty array, it could mean:- None of the player’s Facebook friends have played your game yet
- Friends have played but have revoked permissions
- The player has restricted their friend list visibility in Facebook privacy settings
In this case, your game should handle the empty state gracefully. Consider:
- Showing an invitation prompt (“Invite friends to play together!”)
- Displaying global or contextual leaderboards instead of friend-based ones
- Offering a solo experience that is still engaging
Using Friend Data for Leaderboards
One of the most powerful uses of connected player data is building friend-based leaderboards. The Instant Games SDK provides a dedicated leaderboard API that integrates with connected players. See Leaderboards for full details.
Here is a quick example of combining connected players with leaderboard data:
async function showFriendLeaderboard() { try { const leaderboard = await FBInstant.getLeaderboardAsync('main_score'); const friendEntries = await leaderboard.getConnectedPlayerEntriesAsync(10, 0); friendEntries.forEach(entry => { console.log( `${entry.getRank()}. ${entry.getPlayer().getName()} - ${entry.getScore()}` ); }); } catch (error) { console.error('Failed to load friend leaderboard:', error); } }
Using Friend Data for Challenges
Connected player data enables direct, personal challenges between friends. Here is an example flow:
async function sendChallenge(friendId, myScore) { // Switch to the friend's context to send them a challenge try { await FBInstant.context.createAsync(friendId); await FBInstant.updateAsync({ action: 'CUSTOM', cta: 'Beat My Score!', image: generateChallengeImage(myScore), // Base64-encoded image text: { default: `${FBInstant.player.getName()} scored ${myScore} points. Can you beat it?`, }, template: 'challenge', data: { challengeScore: myScore, challengerId: FBInstant.player.getID(), }, strategy: 'IMMEDIATE', notification: 'PUSH', }); console.log('Challenge sent!'); } catch (error) { console.error('Failed to send challenge:', error); } }
Privacy Considerations
Handling player data responsibly is essential. Facebook’s platform policies require that you:
- Only use player data for in-game purposes. Do not export, sell, or share connected player data with third parties.
- Do not store player data longer than necessary. If you cache friend data on your backend, implement appropriate data retention policies.
- Respect data deletion requests. If a player requests that their data be deleted (through Facebook’s platform or directly), comply promptly.
- Do not use player IDs to track players across games. Player IDs are scoped to your game. Do not attempt to correlate IDs across different games or applications.
- Display data transparently. When you show a player’s friends in your game, it should be clear that the data comes from Facebook and that the player has consented to sharing it.
- Handle permission revocation gracefully. If a player revokes the
user_friendspermission, your game should continue to function without friend data. Do not block gameplay or show error messages that pressure the player to restore permissions.
Best Practices
Show Friends Prominently
Do not hide your friends list in a settings menu. Show connected friends prominently on your main screen, leaderboard, or lobby. The visibility of friends is what drives social engagement.
Even a simple message like “12 of your friends play this game” can boost a new player’s confidence and engagement. Social proof signals that the game is worth playing.
Use Avatars Everywhere
Whenever you display a friend’s name, include their profile photo. Avatars make the experience feel personal and recognizable. Use the URL returned by
getPhoto() to load profile images.Update Friend Data Regularly
Call
getConnectedPlayersAsync() at the start of each session and after significant gameplay events. New friends may start playing between sessions, and you want to surface them as soon as possible.Handle the Zero-Friends Case Well
For new games or new players, the connected players list may be empty. This should not result in a broken or lonely-feeling experience. Provide compelling solo gameplay, show global leaderboards, and encourage the player to invite friends.
Encourage Invitations
When a player has few or no connected friends, prompt them to invite friends. This benefits both the inviter (who gets social features) and your game (which gains new players). Use
FBInstant.context.chooseAsync() to let players select friends to invite.async function inviteFriends() { try { await FBInstant.context.chooseAsync(); console.log('Friend selected, new context:', FBInstant.context.getID()); } catch (error) { // Player cancelled the friend picker console.log('Invitation cancelled'); } }
Cache Friend Data Thoughtfully
If your game makes frequent decisions based on friend data (e.g., showing friend scores on every level), consider caching the results of
getConnectedPlayersAsync() locally during the session rather than calling the API repeatedly. Refresh the cache at natural break points (e.g., returning to the main menu).Matchmaking
In addition to connecting players with existing friends, you can use matchmaking to pair players with other users who are looking for people to play with. Matchmaking creates new Messenger group threads containing matched players and switches the current player into that thread’s context.
Checking eligibility
Before attempting to match a player, check whether they are eligible for matchmaking:
FBInstant.checkCanPlayerMatchAsync() .then(function(canMatch) { if (canMatch) { startMatchmaking(); } else { console.log('Player is not eligible for matchmaking'); } });
Matching players
Use
FBInstant.matchPlayerAsync() to find other players. You can optionally provide a matchTag to group players by criteria such as skill level or game mode. Players are only matched with others who have the exact same tag.FBInstant.matchPlayerAsync('level1') .then(function() { console.log('Player matched!'); // The player is now in a new context with matched players. // Use FBInstant.context.getPlayersAsync() to get the matched players. return FBInstant.context.getPlayersAsync(); }) .then(function(players) { players.forEach(function(player) { console.log('Matched with:', player.getID()); }); });
The default minimum and maximum number of players in a matched thread are 2 and 20 respectively, depending on how many players are trying to get matched around the same time. You can change these values in your app settings.
Offline matchmaking
By default,
matchPlayerAsync() matches players for realtime gameplay. If your game supports asynchronous play (such as turn-based games), you can set the offlineMatch parameter to true to match players without requiring them to be online simultaneously:FBInstant.matchPlayerAsync('casual_mode', false, true) .then(function() { console.log('Async match found!'); });
For the full API reference, see
matchPlayerAsync() and checkCanPlayerMatchAsync().Next Steps
- Leaderboards -- Build competitive leaderboards using connected player data.
- Custom Updates -- Send personalized messages and challenges to friends.
- Tournaments -- Create competitive events for groups of friends.
- Building Social Games -- Learn the strategic principles behind social game design.