# Facebook

> Provide a Facebook sign-in option to enable players to authenticate using their Facebook accounts in your game.

###### 최소 SDK 버전: 2.0.0##minimum-sdk-version-200

이 문서에서는 게임에서 Facebook 계정을 사용해 플레이어의 인증을 설정하는 다음 시나리오에 대해 설명합니다.

> **Note:**
>
> **참고**: 아래 코드 예시에서는 플레이어의 Facebook 액세스 토큰을 이미 획득했다고 가정합니다.
>
> * Facebook 계정 로그인 설정
> * 기존 사용자 로그인 또는 새 사용자 생성
> * 사용자를 익명 로그인에서 Facebook 계정을 통한 플랫폼 로그인으로 업데이트

게임에서 플레이어에게 Facebook 로그인 옵션을 제공하려면 Facebook 개발자 포털에서 앱을 생성한 다음 [Unity용 Facebook SDK](https://developers.facebook.com/docs/unity/downloads)를 설치해 사용자를 로그인 처리하고 액세스 토큰을 가져오십시오.

## Facebook 계정 로그인 설정

아래의 단계에서는 Facebook 앱을 이미 설정했다고 가정합니다.

1. [Facebook의 시작하기 기술 자료](https://developers.facebook.com/docs/unity/gettingstarted)에 따라 Facebook SDK를 설정하고 설치합니다.

2. Unity Authentication의 ID 제공업체로 Facebook을 추가합니다.

   1. Unity 에디터 메뉴에서 **Edit** > **Project Settings…** 로 이동한 후, 내비게이션 메뉴에서 **Services** > **Authentication**을 선택합니다.
   2. **ID Providers**를 **Facebook**으로 설정한 후, **Add**를 클릭합니다.
   3. App ID 텍스트 필드에 앱 ID(1단계에서 찾을 수 있음)를 입력합니다.
   4. **App Secret** 텍스트 필드에 앱 비밀 정보를 입력한 후, **Save**를 클릭합니다.

3. [이 샘플 코드를 사용해](https://developers.facebook.com/docs/unity/examples#login) Facebook 로그인을 구현합니다.

   > **Note:**
   >
   > **참고**: Unity Authentication SDK는 현재 express 로그인 토큰을 지원하지 않습니다.

> **Note:**
>
> **참고**: Facebook SDK는 Unity 2021.1의 플레이 모드에서 정상적으로 작동하지 않으며, [이 GitHub 이슈](https://github.com/facebook/facebook-sdk-for-unity/issues/537)에서 내용을 확인할 수 있습니다. 이를 해결하려면 [이 풀 리퀘스트](https://github.com/facebook/facebook-sdk-for-unity/pull/539/files)에 따라 Facebook.Unity.dll을 빌드하십시오.

> **Note:**
>
> 현재 '소비자'와 '비즈니스' 앱 유형을 지원합니다.

```cs
using System.Collections.Generic;
using UnityEngine;

// Other needed dependencies
using Facebook.Unity;

public class FacebookExampleScript : MonoBehaviour
{
    public string Token;
    public string Error;

    // Awake function from Unity's MonoBehaviour
    void Awake()
    {
        if (!FB.IsInitialized)
        {
            // Initialize the Facebook SDK
            FB.Init(InitCallback, OnHideUnity);
        }
        else
        {
            // Already initialized, signal an app activation App Event
            FB.ActivateApp();
        }
    }

    void InitCallback()
    {
        if (FB.IsInitialized)
        {
            // Signal an app activation App Event
            FB.ActivateApp();
            // Continue with Facebook SDK
        }
        else
        {
            Debug.Log("Failed to Initialize the Facebook SDK");
        }
    }

    void OnHideUnity(bool isGameShown)
    {
        if (!isGameShown)
        {
            // Pause the game - we will need to hide
            Time.timeScale = 0;
        }
        else
        {
            // Resume the game - we're getting focus again
            Time.timeScale = 1;
        }
    }

    public void Login()
    {
        // Define the permissions
        var perms = new List<string>() { "public_profile", "email" };

        FB.LogInWithReadPermissions(perms, result =>
        {
            if (FB.IsLoggedIn)
            {
                Token = AccessToken.CurrentAccessToken.TokenString;
                Debug.Log($"Facebook Login token: {Token}");
            }
            else
            {
                Error = "User cancelled login";
                Debug.Log("[Facebook Login] User cancelled login");
            }
        });
    }
}
```

## 기존 플레이어 로그인 또는 신규 플레이어 생성##sign-in-a-returning-player-or-create-new-player

`SignInWithFacebookAsync` 메서드를 사용하여 다음 중 하나를 수행할 수 있습니다.

* Facebook 자격 증명을 사용해 새 Unity Authentication 플레이어 생성
* Facebook 자격 증명을 사용해 기존 플레이어 로그인

프로젝트에서 자격 증명과 연결된 Unity Authentication 플레이어가 존재하지 않는 경우, `SignInWithFacebookAsync`가 새 플레이어를 생성합니다. 프로젝트에서 자격 증명과 연결된 Unity Authentication 플레이어가 존재하는 경우, `SignInWithFacebookAsync`가 해당 플레이어의 계정으로 로그인합니다. 이 기능은 캐시된 플레이어를 고려하지 않으며, `SignInWithFacebookAsync`가 캐시된 플레이어를 대체합니다.

```cs
async Task SignInWithFacebookAsync(string accessToken)
{
    try
    {
        await AuthenticationService.Instance.SignInWithFacebookAsync(accessToken);
        Debug.Log("SignIn is successful.");
    }
    catch (AuthenticationException ex)
    {
        // Compare error code to AuthenticationErrorCodes
        // Notify the player with the proper error message
        Debug.LogException(ex);
    }
    catch (RequestFailedException ex)
    {
        // Compare error code to CommonErrorCodes
        // Notify the player with the proper error message
        Debug.LogException(ex);
    }
}
```

## 플레이어를 익명 로그인에서 Facebook 계정 로그인으로 업데이트##update-a-player-from-anonymous-to-a-facebook-account

익명 인증을 설정한 후, 플레이어가 Facebook 계정을 생성하고 Facebook을 통해 로그인하도록 업그레이드하려는 경우, 게임이 플레이어에게 Facebook 로그인 창을 표시하고 Facebook에서 액세스 토큰을 가져와야 합니다. 그런 다음 `LinkWithFacebookAsync` API를 호출해 플레이어를 Facebook 액세스 토큰에 연결합니다.

SDK에 캐시된 플레이어가 존재하는 경우, 캐시된 플레이어를 Facebook 계정에 연결할 수 있습니다.

1. `SignInAnonymouslyAsync`를 사용해 캐시된 플레이어의 계정에 로그인합니다.
2. `LinkWithFacebookAsync`를 사용해 캐시된 플레이어의 계정을 Facebook 계정에 연결합니다.

```cs
async Task LinkWithFacebookAsync(string accessToken)
{
    try
    {
        await AuthenticationService.Instance.LinkWithFacebookAsync(accessToken);
        Debug.Log("Link is successful.");
    }
    catch (AuthenticationException ex) when (ex.ErrorCode == AuthenticationErrorCodes.AccountAlreadyLinked)
    {
        // Prompt the player with an error message.
        Debug.LogError("This user is already linked with another account. Log in instead.");
    }
    catch (AuthenticationException ex)
    {
        // Compare error code to AuthenticationErrorCodes
        // Notify the player with the proper error message
        Debug.LogException(ex);
    }
    catch (RequestFailedException ex)
    {
        // Compare error code to CommonErrorCodes
        // Notify the player with the proper error message
        Debug.LogException(ex);
    }
}
```

플레이어가 로그인하거나 새 플레이어 프로필을 생성해 Facebook 로그인을 트리거하고 Facebook 액세스 토큰을 가져온 경우, 다음 API를 호출해 플레이어를 인증합니다.

```cs
async Task SignInWithFacebookAsync(string accessToken)
{
    try
    {
        await  AuthenticationService.Instance.SignInWithFacebookAsync(accessToken);
        Debug.Log("SignIn is successful.");
    }
    catch (AuthenticationException ex)
    {
        // Compare error code to AuthenticationErrorCodes
        // Notify the player with the proper error message
        Debug.LogException(ex);
    }
    catch (RequestFailedException ex)
    {
        // Compare error code to CommonErrorCodes
        // Notify the player with the proper error message
        Debug.LogException(ex);
    }
}
```

## Facebook 로그인 인증 구현##implement-a-facebook-sign-in-authentication

플레이어가 로그인하거나 새 플레이어 프로필을 생성해 Facebook 로그인을 트리거하고 Facebook 액세스 토큰을 가져온 경우, `SignInWithFacebookAsync(string accessToken)` API를 호출해 플레이어를 로그인 처리합니다.

## Facebook 계정 연결 해제##unlink-facebook-account

플레이어가 Facebook 계정 연결을 해제할 수 있도록 `UnlinkFacebookAsync` API를 사용합니다. 연결이 해제되면 계정이 다른 ID에 연결되지 않은 경우 익명 계정으로 전환됩니다.

```cs
async Task UnlinkFacebookAsync(string idToken)
{
   try
   {
       await AuthenticationService.Instance.UnlinkFacebookAsync(idToken);
       Debug.Log("Unlink is successful.");
   }
   catch (AuthenticationException ex)
   {
       // Compare error code to AuthenticationErrorCodes
       // Notify the player with the proper error message
       Debug.LogException(ex);
   }
   catch (RequestFailedException ex)
   {
       // Compare error code to CommonErrorCodes
       // Notify the player with the proper error message
       Debug.LogException(ex);
   }
}
```
