Code
Allow game makers to manage player accounts
Overview
This guide includes everything needed to use the AuthService in the "Beamable SDK for Unity".
Upon Beamable initialization, the current session is automatically granted a user token. Each time the game is started, the same user token is applied. This allows Beamable to consistently authorize the player and track the player's behavior across a range of Beamable features.
Gotchas
Here are hints to help explain some of the trickier concepts:
• The notion of "Signing in" to an account can be misleading, because the game always ensures there is a player token loaded, even it is an anonymous user with no credentials.
Players can update the active users's info or add third-party credentials to the access token, which can be used to retrieve the token at a later date, or on a separate device.
Update Active User Info
await _beamableAPI.AuthService.RegisterDBCredentials(email, password);
API
Learning Fundamentals
Game makers who are new to Unity and C# can review the fundamentals here.
• See Beamable: Asynchronous Programming for more info
Here are API highlights for beamableAPI.AuthService
.
Method Name | Detail |
---|---|
CreateUser | Create new active user |
GetCurrentProject | Get the active project info |
GetUser | Get the active user info |
LoginThirdParty | Login the active user via AuthThirdParty integrations |
RegisterDBCredentials | Update the email and password for the active user |
Examples
Here are examples which cover common programming needs.
Beamable SDK Examples
• The following example code is available for download at GitHub.com/Beamable_SDK_Examples
This AuthServiceExample.cs
demonstrates CreateUser()
, RegisterDBCredentials()
, and more.
using System.Collections.Generic;
using System.Threading.Tasks;
using Beamable.Api;
using Beamable.Common.Api;
using Beamable.Common.Api.Auth;
using UnityEngine;
using UnityEngine.Events;
using Random = UnityEngine.Random;
namespace Beamable.Examples.Services.AuthService
{
/// <summary>
/// Holds data for each mock user to toggle between for demo
/// </summary>
public class MockUser
{
public string Alias = "";
public string Email = "";
public string Password = "";
public MockUser(string alias, string email, string password)
{
Alias = alias;
Password = password;
Email = email;
}
// Randomize for demo usage
public static string GetMockEmail(string index)
{
return "blah@blah" + Random.Range(10000, 99999) + "_" + index + ".com";
}
}
/// <summary>
/// Holds data for use in the <see cref="AuthServiceExampleUI"/>.
/// </summary>
[System.Serializable]
public class AuthServiceExampleData
{
public List<string> MainTexts = new List<string>();
public List<string> DetailTexts = new List<string>();
public bool IsBeamableSetup = false;
}
[System.Serializable]
public class AuthServiceExampleExampleEvent : UnityEvent<AuthServiceExampleData> { }
/// <summary>
/// Demonstrates <see cref="AuthService"/>.
///
/// NOTE: The notion of "Signing in" to an account can be misleading, because
/// the game always ensures there is a player token loaded, even it is an anonymous
/// user with no credentials.
///
/// </summary>
public class AuthServiceExample : MonoBehaviour
{
// Events ---------------------------------------
[HideInInspector]
public AuthServiceExampleExampleEvent OnRefreshed = new AuthServiceExampleExampleEvent();
// Fields ---------------------------------------
private IBeamableAPI _beamableAPI;
private AuthServiceExampleData _authServiceExampleData = new AuthServiceExampleData();
private MockUser _mockUser01 = null;
private MockUser _mockUser02 = null;
private string _lastRegisteredEmail = "";
// Unity Methods --------------------------------
protected void Start()
{
Debug.Log($"Start()");
// Create 2 new mock users for demo purposes
string mockEmail01 = MockUser.GetMockEmail("01");
string mockEmail02 = MockUser.GetMockEmail("02");
_mockUser01 = new MockUser ("Alias01", mockEmail01, "myPasswordFoo");
_mockUser02 = new MockUser ("Alias02", mockEmail02, "myPasswordBar");
SetupBeamable();
}
protected void OnDestroy()
{
// Unsubscribe to events
_beamableAPI.OnUserChanged += BeamableAPI_OnUserChanged;
_beamableAPI.OnUserLoggingOut += BeamableAPI_OnUserLoggingOut;
}
// Methods --------------------------------------
private async void SetupBeamable()
{
_beamableAPI = await Beamable.API.Instance;
Debug.Log($"beamableAPI.User.id = {_beamableAPI.User.id}");
// Create 2 new users from mock users for demo purposes,
// Then later from UI: switch and update the active user
_authServiceExampleData.DetailTexts.Clear();
await CreateUser(_mockUser01.Alias);
await UpdateCurrentUser();
await CreateUser(_mockUser02.Alias);
await UpdateCurrentUser();
_authServiceExampleData.IsBeamableSetup = _beamableAPI != null;
// Subscribe to events
_beamableAPI.OnUserChanged += BeamableAPI_OnUserChanged;
_beamableAPI.OnUserLoggingOut += BeamableAPI_OnUserLoggingOut;
Refresh();
}
private async Task<EmptyResponse> CreateUser(string alias)
{
var tokenResponse = await _beamableAPI.AuthService.CreateUser();
await _beamableAPI.ApplyToken(tokenResponse);
await _beamableAPI.StatsService.SetStats("public", new Dictionary<string, string>()
{
{ "alias", alias },
});
string detailText = $"CreateUser() Alias = {alias}";
_authServiceExampleData.DetailTexts.Add(detailText);
return new EmptyResponse();
}
public void Refresh()
{
//Debug.Log($"Refresh()");
if (_authServiceExampleData.IsBeamableSetup)
{
_authServiceExampleData.MainTexts.Clear();
string mainText = $"Active User.Id = {_beamableAPI.User.id}, User.Email = {_beamableAPI.User.email}";
_authServiceExampleData.MainTexts.Add(mainText);
}
OnRefreshed?.Invoke(_authServiceExampleData);
}
/// <summary>
/// Attach an email/password to active user
/// </summary>
public async Task<EmptyResponse> UpdateCurrentUser()
{
// Choose the OTHER mock user
MockUser nextMockUser = _mockUser02;
if (_lastRegisteredEmail != _mockUser01.Email)
{
nextMockUser = _mockUser01;
}
bool isSuccess = false;
string error = "";
try
{
// This method actually changes the active Beamable user
var user = await _beamableAPI.AuthService.RegisterDBCredentials(nextMockUser.Email,
nextMockUser.Password);
isSuccess = true;
}
catch (PlatformRequesterException e)
{
// Errors if: The email has either already been taken by another account, or
// The current account already has an email.
error = e.Message;
}
// Update UI
_authServiceExampleData.DetailTexts.Clear();
string detailText = $"UpdateCurrentUser() User.id = {_beamableAPI.User.id}, nextMockUser.Email = {nextMockUser.Email}, isSuccess = {isSuccess}";
Debug.Log(detailText);
_authServiceExampleData.DetailTexts.Add(detailText);
if (isSuccess)
{
_lastRegisteredEmail = nextMockUser.Email;
}
else
{
string warningText = $"\nThat email was already registered. That is ok.";
_authServiceExampleData.DetailTexts.Add(warningText);
//Debug.Log(warningText);
}
Refresh();
return new EmptyResponse();
}
public async Task<EmptyResponse> SwitchCurrentUser()
{
// Choose the OTHER mock user
MockUser nextMockUser = _mockUser02;
if (_beamableAPI.User.email != _mockUser01.Email)
{
nextMockUser = _mockUser01;
}
Debug.Log($"SwitchCurrentUser() From User.id = {_beamableAPI.User.id}");
bool isSuccess = false;
string error = "";
TokenResponse tokenResponse = null;
try
{
bool mergeUserIdToAccount = false;
tokenResponse = await _beamableAPI.AuthService.Login(nextMockUser.Email,
nextMockUser.Password, mergeUserIdToAccount);
isSuccess = true;
}
catch (PlatformRequesterException e)
{
// Errors if: No account with that email exists yet
error = e.Message;
}
// Update UI
_authServiceExampleData.DetailTexts.Clear();
string detailText = $"SwitchCurrentUser() To User.Email = {nextMockUser.Email}, isSuccess = {isSuccess}";
if (!isSuccess)
{
detailText += $", Error = {error}";
}
else
{
// This method actually changes the active Beamable user
await _beamableAPI.ApplyToken(tokenResponse);
}
Debug.Log(detailText);
_authServiceExampleData.DetailTexts.Add(detailText);
Refresh();
return new EmptyResponse();
}
// Event Handlers -------------------------------
private void BeamableAPI_OnUserLoggingOut(User user)
{
Debug.Log($"OnUserLoggingOut() User.id = {user.id}");
}
private void BeamableAPI_OnUserChanged(User user)
{
Debug.Log($"OnUserChanged() User.id = {user.id}");
}
}
}
Advanced
This section contains any advanced configuration options and workflows.
Auth Token Storage
The Beamable access tokens are stored for reuse within an active auth session.
- Unity Play Mode (Runtime) -
path/is/tbd/
- Unity Edit Mode -
path/is/also/tbd
User Events
User events are available for advanced usage.
Subscribe To Events
var beamableAPI = await Beamable.API.Instance;
beamableAPI.OnUserChanged += BeamableAPI_OnUserChanged;
beamableAPI.OnUserLoggingOut += BeamableAPI_OnUserLoggingOut;
See the AuthServiceExample.cs
above for a full demonstration.
Updated 6 months ago