Appearance
Appearance
Social logins are a way to use third-party identity providers to identify a player to the game server. This allows players to connect from multiple different devices and still see the same Game Account. Social logins also make it possible to import personal information, such as the player’s name, friends, into your game.
Pro tip
Lost accounts are typically the number one customer support request in large games. Implementing social logins is the most effective first step in cutting down on these support requests!
This is a quick guide on how to set up a Development Platform for social logins that allows you to test different scenarios and verify the game handles the authentication flows correctly.
For example, if you need to test out app-side login flow integration for Facebook, or some other non-editor supported Social Platform, you'd otherwise need to run device builds and create elaborate player account setups to test various cases. With the Development Platform, you can replace calls to Facebook Login with the development platform.
The intended use of the Development Platform is to serve as a temporary placeholder for real Social Platforms during development.
Note
The Development Platform is only accepted by the server if the Environment:EnableDevelopmentFeatures
runtime option is true
. This is the case when running the server locally or in development environment, but not in staging or production.
On the client, the validation is initiated by passing the relevant authentication claim to MetaplayClient.SocialAuthManager.StartValidation()
. For example, to associate the client Game Account with a Social Account dev:0000001
, do the following:
void OnLoggedIn(GoogleSignInUser user)
{
string authToken = "{\"id\":\"dev:0000001\" }";
SocialAuthenticationClaimDevelopment claim = new SocialAuthenticationClaimDevelopment(authToken);
MetaplayClient.SocialAuthManager.StartValidation(claim);
}
The client also needs to implement the IMetaplayClientSocialAuthenticationDelegate
in its ApplicationStateManager
(or equivalent):
// ApplicationStateManager.cs
public class ApplicationStateManager : MonoBehavior, IMetaplayClientSocialAuthenticationDelegate
{
void Start()
{
// Inform Metaplay that this class implements the social auth delegate
MetaplaySDK.Initialize(new MetaplayClientOptions
{
// ...
// Listen to social authentication validation responses from the server
SocialAuthenticationDelegate = this,
});
}
#region IMetaplayClientSocialAuthenticationDelegate
void IMetaplayClientSocialAuthenticationDelegate.OnSocialAuthenticationSuccess(AuthenticationPlatform platform)
{
Debug.Log($"Social authenticate success for {platform}");
}
void IMetaplayClientSocialAuthenticationDelegate.OnSocialAuthenticationFailure(AuthenticationPlatform platform, SocialAuthenticateResult.ResultCode errorCode, string debugOnlyErrorMessage)
{
Debug.Log($"Social authenticate failure for {platform} with {errorCode}: {debugOnlyErrorMessage ?? "<hidden>"}");
}
void IMetaplayClientSocialAuthenticationDelegate.OnSocialAuthenticationConflict(AuthenticationPlatform platform, int conflictResolutionId, IPlayerModelBase conflictingPlayer)
{
Debug.Log($"Social authenticate conflict for {platform} with player: id={conflictingPlayer.PlayerId}, level={conflictingPlayer.PlayerLevel}, name={conflictingPlayer.PlayerName}");
<!-- markdownlint-disable-next-line MPL006 -->
// \todo Show dialog to user to choose between currently active PlayerModel or conflictingPlayer
// Based on the player's choice, inform the server which player state we want to keep using:
// useOther == false -- keep using the current player state, and attach the social authentication method to this player
// useOther == true -- keep the social authentication attached to the conflicting player, and switch this device to use that player
// Here, we simulate that the player always chooses to continue with the conflicting player state.
bool useOther = true;
Debug.Log($"Resolve social platform profile conflict with useOther={useOther}");
MetaplayClient.SocialAuthManager.ResolveConflict(conflictResolutionId, useOther);
}
void IMetaplayClientSocialAuthenticationDelegate.OnSocialAuthenticationConflictWithFailingOtherPlayer(AuthenticationPlatform platform, int conflictResolutionId, EntityId conflictingPlayerId)
{
Debug.LogError($"Social authenticate conflict for {platform} with player id={conflictingPlayerId}, but the server failed to get the other player's state");
// \note This is a rare case and usually happens because the other player failed to deserialize.
// The failure is likely a bug and should be invesgiated by the developer.
<!-- markdownlint-disable-next-line MPL006 -->
// \todo Show dialog and let user choose what to do:
// - Leave the auth conflict unresolved, and possibly contact customer support
// - Retry, in hopes the failure was transient (could retry by just restarting game)
// - Resolve the conflict in favor of the current PlayerModel (shouldn't choose the other state because it's possibly broken)
// This stub implementation just leaves the conflict unresolved.
}
#endregion // IMetaplayClientSocialAuthenticationDelegate
}
Here are some examples of how you would test different scenarios using the Development Platform we just implemented in the Quick Guide:
SocialAuthenticationClaimDevelopment("dev1", "{\"id\":\"dev:0000001\" }")
claim. Close the game in the editor and simulate an uninstall by clearing the editor's game credentials (Metaplay → Clear Credentials
). Start the game again. Observe that the game is reset.new SocialAuthenticationClaimDevelopment("dev1", "{\"force_failure\":true}")
.Social Platforms' usually behave as follows:
[ Initializing ]
| |
| '--------------.
V V
[ Logged Out ] <---- [ Logged In ]
| ^ ^
V | |
[ Logging In ] |
| |
'-----------------'
This state graph is tied to application lifetime and therefore the states are not persistent between sessions. Bellow is a second state graph illustrating the attaching of Social Accounts to Game Accounts.
[ Session Start ]
| |
| V
| [ Account Not Attached ]
| | ^ ^
| V | |
| [ Validating ] | |
| | | | | |
| | | '----' |
| | V |
| | [ Conflict ] |
| | | |
V V V |
[ Account Attached ] |
| |
'---------------'
Note that there might be multiple Social Accounts associations happening at the same time, as many as the amount of Social Platforms you decide to integrate into your game. In any case, the loss of internet connection will reset any ongoing validations or conflict resolutions. Here are brief descriptions of the states and their transitions:
Session Start
is a pseudo-state that represents the time before the session has been established. When a session is established, the Game Account (represented by PlayerModel
) is either Attached
or Not Attached
to an Account on each Social Platform.
In Account Not Attached
state, no Social Account of the Social Platform is associated to the Game Account. When the client sends a SocialAuthenticateRequest
to the server the state transitions into Validating
.
In Validating
state, the server checks that the claim of being associated with the Social Account is true. This may require the server to make requests to the APIs of the corresponding Social Platform. Generally, this state completes fast but due to dependency on third-party services, may take some time in exceptional circumstances.
If validation fails, i.e. the server cannot verify the claim to be genuine, the server informs the client with a SocialAuthenticateResult
message with IsSuccess = false
, and state transitions back to Account Not Attached
.
If validation succeeds, and the server informs the client with SocialAuthenticateResult
with IsSuccess = true
. If attaching the account would cause a conflict (see Managing Conflicting Social Logins ), a transition to Conflict
is made. In this case, the ConflictingPlayerId
field of SocialAuthenticateResult
has the EntityId
of the conflicting Game Account. Additionally, the ConflictingPlayerIfAvailable
field has the serialized PlayerModel
corresponding to that EntityId
, except in the rare case that the server failed to query that PlayerModel
(for example due to deserialization failure).
Otherwise, if there is no conflict, the Social Account is attached to the Game Account, and ConflictingPlayer
field in SocialAuthenticateResult
contains a null value. The state is transitioned into Account Attached
.
In Conflict
state, the Social Account claim has been validated but attaching it to the current Game Account would cause a conflict and require conflict resolution. After choosing the desired resolution (see Managing Conflicting Social Logins ), the client may resolve the conflict by sending a SocialAuthenticateResolveConflict
message. This transitions the state into Account Attached
.
In Account Attached
state the Social Account is attached to the game account. To detach the Social Account, the client may send SocialAuthenticateDetach
message. This transitions the state back to Account Not Attached
DANGER
In this guide we haven't implemented conflict management: There are cases where a player will try to log in with a Social Account that's already attached to a Game Account. In these cases, the client needs to decide what to do. Before implementing social logins with a real Social Platform you should take a look at Managing Conflicting Social Logins.
Before implementing social logins with a real Social Platform, it's necessary to handle conflict management. For that, please check out Managing Conflicting Social Logins. It's very important you don't skip this step. The good news is, you only have to do it once because the logic is the same for every platform. After that, you can integrate one or more social logins of your choosing.
The Metaplay SDK ships with pre-configured support for the most popular Social Platforms. Have a look at the detailed implementation guides to get started: