Useful Information: Pulling Player IDs and Information with Cloud Script and HttpClient

How to access all players’ data both from Unity and with Cloud Script?

A-1) List all user ids directly with Unity Script:

Go to the Administration menu, create an api in the Service Accounts section and assign the desired authorizations.

Note: You can also assign the encodedCredentials part by creating it in base64 type with other programs. But in the future, considering the change of key or scret id, we created it instantly in the code.

private async void Start()
{
    string keyId = "YOUR SERVICE ACCOUNT SERVICE KEY";
    string secretKey = "YOUR SERVICE ACCOUNT SERVICE SECRET KEY";
    string projectId = "PROJECT ID";
    string credentials = $"{keyId}:{secretKey}";
    string encodedCredentials = Convert.ToBase64String(Encoding.UTF8.GetBytes(credentials));

    await FetchAllUserIds(encodedCredentials, projectId);
    
}

 private async Task FetchAllUserIds(string encodedCredentials, string projectId)
 {
     try
     {
         string url = $"https://services.api.unity.com/player-identity/v1/projects/{projectId}/users";
         client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", encodedCredentials);
         client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

         HttpResponseMessage response = await client.GetAsync(url);
         string responseBody = await response.Content.ReadAsStringAsync();

         Debug.Log($"Response Status: {response.StatusCode}");
         Debug.Log($"Response Body: {responseBody}");

         if (response.IsSuccessStatusCode)
         {
             // Parse the response JSON and print user IDs
             var jsonResponse = JsonConvert.DeserializeObject<ResponseData>(responseBody);
             if (jsonResponse != null && jsonResponse.results != null)
             {
                 if (jsonResponse.results.Length > 0)
                 {
                     foreach (var player in jsonResponse.results)
                     {
                         Debug.Log($"Player ID: {player.id}");
                     }
                 }
                 else
                 {
                     Debug.Log("No players found in the response.");
                 }
             }
             else
             {
                 Debug.LogError("Invalid response format or no players found.");
             }
         }
         else
         {
             Debug.LogError($"Failed to fetch user IDs: {response.StatusCode}");
         }
     }
     catch (Exception e)
     {
         Debug.LogError($"Exception occurred: {e.Message}");
     }
 }

[Serializable]
public class Player
{
    public string id;
    public long createdAt;
    public bool disabled;
    public string[] externalIds;
    public long lastLoginAt;
}

[Serializable]
public class ResponseData
{
    public string next;
    public Player[] results;
}

This code will return the ID of all users registered in your game.

A-2) Accessing the data in the Player data of any ID with Unity Script

You will need an extra environment Id for this section.

private async Task GetCloudDataKey(string encodedCredentials, string projectId, string environmentId, string userId, string dataKey)
{
    try
    {
        string url = $"https://services.api.unity.com/cloud-save/v1/data/projects/{projectId}/environments/{environmentId}/players/{userId}/items?keys={dataKey}";
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", encodedCredentials);
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

        HttpResponseMessage response = await client.GetAsync(url);
        string responseBody = await response.Content.ReadAsStringAsync();

        Debug.Log($"Response Status: {response.StatusCode}");
        Debug.Log($"Response Body: {responseBody}");

        if (response.IsSuccessStatusCode)
        {
            var jsonResponse = JObject.Parse(responseBody);
            var managerNameValue = jsonResponse["results"]?.First?["value"]?.ToString();
            if (!string.IsNullOrEmpty(managerNameValue))
            {
                Debug.Log($"Manager_Name Value: {managerNameValue}");
            }
            else
            {
                Debug.Log("Manager_Name key not found or has no value.");
            }
        }
        else if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
        {
            Debug.LogError("Data not found for the given user ID. Please check if the user ID is correct and if the data exists.");
        }
        else
        {
            Debug.LogError($"Failed to fetch cloud data: {response.StatusCode} - {response.ReasonPhrase}");
        }
    }
    catch (Exception e)
    {
        Debug.LogError($"Exception occurred: {e.Message}");
    }
}

You should request this method asynchronously. With any user id, you need to specify the data you want as a string. Ex:

 await GetCloudDataKey(encodedCredentials, projectId, environmentId, userId, cloudDataKey);

B-1) List all player ids using cloud script:

Create a clud script and fill in keyId, secret key, projectId.

const axios = require('axios');
const keyId = 'YOUR SERVICE KEY ID';
const secretKey = 'YOUR SERVICE SECRET KEY';
const projectId = 'PROJECT ID';

const credentials = `${keyId}:${secretKey}`;
const encodedCredentials = Buffer.from(credentials).toString('base64');

async function fetchAllUserIds() {
    try {
        console.log('Starting API call');
        console.log(`Using encoded credentials: ${encodedCredentials}`);
        const response = await axios.get(`https://services.api.unity.com/player-identity/v1/projects/${projectId}/users`, {
            headers: {
                'Authorization': `Basic ${encodedCredentials}`,
                'Content-Type': 'application/json'
            }
        });

        // Yanıtın tamamını kontrol et ve logla
        console.log('API response:', response.data);
        console.log('Response headers:', response.headers);
        console.log('Response status:', response.status);

        // Yanıtın yapısını kontrol et
        if (response.status === 200) {
            const users = response.data.results;
            if (users && users.length > 0) {
                users.forEach(user => {
                    console.log(`Player ID: ${user.id}`);
                });
                return users;
            } else {
                console.log('No players found.');
                console.log('Response data:', response.data);
            }
        } else {
            console.error(`Failed to fetch user IDs: ${response.status} - ${response.statusText}`);
            console.error('Response data:', response.data);
        }
    } catch (error) {
        console.error(`Error fetching user IDs: ${error}`);
        if (error.response) {
            console.error('Error response data:', error.response.data);
            console.error('Error response headers:', error.response.headers);
            console.error('Error response status:', error.response.status);
        }
        throw error;
    }
}

module.exports = fetchAllUserIds;

Then call this script in unity.

**

B-2: Calling Cloud Data data from Unity with Cloud Code

**

const axios = require('axios');

const keyId = 'key id';
const secretKey = 'secret key';
const projectId = 'project id';
const environmentId = 'environment Id ';

const credentials = `${keyId}:${secretKey}`;
const encodedCredentials = Buffer.from(credentials).toString('base64');

async function getData(userId, keyName) {
  try {
    const url = `https://services.api.unity.com/cloud-save/v1/data/projects/${projectId}/environments/${environmentId}/players/${userId}/items?keys=${keyName}`;
    const response = await axios.get(url, {
      headers: {
        'Authorization': `Basic ${encodedCredentials}`,
        'Content-Type': 'application/json'
      }
    });

    if (response.status === 200) {
      const results = response.data.results;
      if (results && results.length > 0) {
        return results[0].value;
      } else {
        return null;
      }
    } else {
      throw new Error(`Failed to fetch data: ${response.status} - ${response.statusText}`);
    }
  } catch (error) {
    throw error;
  }
}

module.exports = async ({ params, context }) => {
  const userId = params.userId;
  const keyName = params.keyName;
  const value = await getData(userId, keyName);
  return { value };
};

Through Unity, you get value type return by sending user id and key.

 private async Task<string> CallGetPlayerDataFunction(string userId, string keyName)
    {
        try
        {
            var parameters = new Dictionary<string, object>
            {
                { "userId", userId },
                { "keyName", keyName }
            };

            var result = await CloudCodeService.Instance.CallEndpointAsync<CloudCodeResponse>("GetPlayerData", parameters);
            Debug.Log($"Cloud Code function result: {result.value}");
            return result.value;
        }
        catch (CloudCodeException e)
        {
            Debug.LogError($"Cloud Code call failed: {e.Message}");
            return null;
        }
    }

    [Serializable]
    public class CloudCodeResponse
    {
        public string value;
    }

Example use:

string managerName = await CallGetPlayerDataFunction(userId, keyName);
 Debug.Log($"Manager_Name for user {userId}: {managerName}");

I hope it will be useful. Good work!

1 Like