[SKKU DT] 30일차 -유니티 네트워크 -파이어베이스(Firebase) Authentication 로그인, 익명 로그인

2023. 12. 11. 18:18SKKU DT

728x90
반응형

Firebase란?

-Google에서 제공하는 클라우드 기반의 개발 플랫폼. 사용자 인증(로그인 서비스), 실시간 데이터베이스, 분석, 파일 스토리지 등을 포함한 많은 기능을 지원한다.

-WhatsApp, Snapchat, Airbnb, Uber, Instagram, Twitter 등...

 

 

Firebase 주요 기능

Firebase Authentication: 이베일, 비밀번호, 여러 소셜 미디어 계정을 통한 인증을 제공한다.

Realtime Database: 실시간 데이터베이스는 NoSQL 데이터베이스. 데이터를 실시간으로 동기화하여 모든 클라이언트에 반영한다.

Firebase Cloud Storage: 사용자 콘텐츠를 저장하고 공유하는 안전한 파일 호스팅 서비스를 제공한다.

 

 

Firebase의 장점

신뢰할 수 있는 확장 데이터베이스

빠르고 안전한 호스팅: 다양한 콘텐츠 유형에 대한 호스팅 지원, SSL 강화된 보안 기능, SSD 및 CDN 지원으로 빠른 콘텐츠 전송 제공

구글 애널리틱스 통합: 사용자 행동 분석 및 광고, 기타 도구와 통합 가능.

Firebase 클라우드 메시징: 비용 없이 알림을 보낼 수 있는 크로스 플랫폼 메시지 솔루션 제공.

 

 

Firebase의 단점

폐쇄 소스 플랫폼: 개발자가 Firebase 코드를 변경할 수 없어 플랫폼 제어가 제한적이다.

벤더 락인: 다른 플랫폼으로 앱을 이전할 수 없어 벤더에 종속될 수 있다.

복잡한 요금 책정

SQL 데이터베이스 미지원: NoSQL 데이터베이스만 지원하므로 관계형 데이터베이스 구조를 지원하지 않는다.

 

 

Firebase 서버 서비스

 

 


 

 

유니티에서 파이어베이스 활용하기

유니티 프로젝트를 하나 만들고 [Project Settings] - [Player]에서 Company Name과 Product Name을 설정할 수 있다.

 

 

중간에 [Mac App Store Options] - [Bundle Identifier]가 설정한 이름으로 바뀐다.

 

 

파이어베이스 홈페이지에 들어가서 가입한다.

https://firebase.google.com/?hl=ko

 

Firebase | Google’s Mobile and Web App Development Platform

개발자가 사용자가 좋아할 만한 앱과 게임을 빌드하도록 지원하는 Google의 모바일 및 웹 앱 개발 플랫폼인 Firebase에 대해 알아보세요.

firebase.google.com

 

 

성공적으로 프로젝트를 만들었다면 아래와 같은 화면이 뜨게 된다. 화면 가운데에 유니티 모양의 버튼을 클릭한다.

 

 

Project Settings에서 설정했던 Bundle Identifier를 Android 패키지 이름에 넣는다.

 

 

지시대로 json을 Asset폴더에 넣는다.

 

 

지시대로 SDK 파일을 받아서 압축을 푼다.

 

 

[Assets] - [Import Package] - [Custom Package...] 에서 방금 받았던 압축 파일을 푼 경로를 찾는다.

 

 

FirebaseAnalytics.unitypackage, FirebaseAuth.unitypackage를 선택하고 import 한다.

 

 

json이 업데이트가 되었지만 ios 적용이 아직 되지 않아서 오류가 날 수 있다.

 

 

오류를 지우는 법은 [Firebase] - [Editor] - [Firebase Editor]에서 [Define Constraints]를 UNITY_IOS로 입력하고,

[ExternalDependency] - [Google.IOSResolver] 에서 모든 체크를 해제하고 Apply하면 된다.

 

 

다시 Firebase 홈페이지에서 내 프로젝트 설정에 들어가면 google-services.json을 다시 받을 수 있다.

 

 

새로 받은 json에는 oauth_client와 api_key키가 생성된 것을 볼 수 있다. Assets 폴더에서 해당 json을 바꿔준다.

 

 

이후 Firebase 홈페이지에서 [Authentication]을 눌러 시작하기를 누르면 된다.

 

 

그러면 인증할 수 있는 많은 방법들이 있다.

 

 

이메일/비밀번호 를 사용한다고 설정하면 이메일/비밀번호 인증을 할 수 있게 된다.

 

 


 

 

이제 유니티에서 스크립트를 생성한다. 비밀번호와 패스워드를 받아서 계정을 생성하는 버튼, 로그인, 로그아웃 버튼을 생성해야 한다. Firebase.Auth 네임스페이스를 추가한다.

using Firebase.Auth;

 

 

Create, LogIn, LogOut 함수를 사용할 것이다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Firebase.Auth;
using TMPro;


public class FirebaseAuthManager : MonoBehaviour
{
    private FirebaseAuth auth; //인증을 위한 변수 선언
    public TMP_InputField email;
    public TMP_InputField password;
    public TMP_Text action; //로그인을 했는지 로그아웃을 했는지 알려주는 창(생략 가능)
    void Start()
    {
        auth = FirebaseAuth.DefaultInstance;
    }

    public void Create() //계정 생성
    {

    }

    public void LogIn() //로그인 함수
    {

    }

    public void LogOut() //로그아웃 함수
    {
        auth.SignOut();
        Debug.Log("로그아웃"); //로그아웃 확인
    }
}

 

 

함수의 내용을 작성한다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Firebase.Auth;
using TMPro;


public class FirebaseAuthManager : MonoBehaviour
{
    private FirebaseAuth auth; //인증을 위한 변수 선언
    public TMP_InputField email;
    public TMP_InputField password;
    void Start()
    {
        auth = FirebaseAuth.DefaultInstance;
    }

    public void Create() //계정 생성
    {
        auth.CreateUserWithEmailAndPasswordAsync(email.text, password.text).ContinueWith(task => //람다식, 결과는 task가 나온다.
        {
            if(task.IsFaulted) //계정을 만들지 못했을 경우,
            {
                Debug.Log("계정 생성 실패");
                return;
            }
            if(task.IsCanceled) //계정 생성을 실패했을 경우(네트워크 장애, 도중 취소)
            {
                Debug.Log("계정 생성 취소");
                return;
            }
            FirebaseUser newUser = task.Result.User; //계정을 만들지 못하거나 실패했을 경우가 아닐 경우
        });
    }

    public void LogIn() //로그인 함수 계정 생성과 동일한 코드 복붙, 수정
    {
        auth.SignInWithEmailAndPasswordAsync(email.text, password.text).ContinueWith(task => //람다식, 결과는 task가 나온다.
        {
            if (task.IsFaulted) //로그인을 못했을 경우,
            {
                Debug.Log("로그인 실패");
                return;
            }
            if (task.IsCanceled) //로그인을 실패했을 경우(네트워크 장애, 도중 취소)
            {
                Debug.Log("로그인 취소");
                return;
            }
            Debug.Log("로그인 성공");
        });
    }

    public void LogOut() //로그아웃 함수
    {
        auth.SignOut();
        Debug.Log("로그아웃"); //로그아웃 확인
    }
}

 

 


 

 

유니티에서 로그인 UI 만들기

InputField, Button을 만들어서 연결한다.

 

 

실행을 하면 오류가 뜨는데, [Assets] 폴더 아래에 [StreamingAssets] 폴더를 만들어서 json을 넣는다.

 

 

이메일 형식과 비밀번호를 입력하고 Create하면 계정이 만들어지고, 로그인, 로그아웃이 된다.

 

 


 

 

새로운 FirebaseController 스크립트를 하나 만든다. 유저 고유 ID를 컨트롤 하는 스크립트이다.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Firebase.Auth;
using System.Threading.Tasks; //Task문법을 사용할 예정
using TMPro;
using Firebase.Extensions;
using System;

public class FirebaseController : MonoBehaviour
{
    private FirebaseAuth auth;
    private FirebaseUser user;
    void Start()
    {
        Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => //버전이 맞는지 체크
        {
            if(task.Result == Firebase.DependencyStatus.Available) //괜찮으면, 문제 없이 시작된다면,
            {
                FirebaseInit();
            }
            else //괜찮지 않다면
            {
                Debug.LogError("");
            }
        });
    }
    private void FirebaseInit()
    {
        auth = FirebaseAuth.DefaultInstance;
        auth.StateChanged += AuthStateChanged; //상태 변화가 있으면 함수를 불러와라
    }
    private void AuthStateChanged(object sender, EventArgs e)
    {
        FirebaseAuth senderAuth = sender as FirebaseAuth; //무슨 일이 생기면 sender와 EventArgs e가 작용한다.
        if(senderAuth != null) //유저가 있다면
        {
            user = senderAuth.CurrentUser;
            if(user != null) //유저가 무엇을 하려 하면(null이 아니면)
            {
                Debug.Log(user.UserId);
            }
        }
    }
}

 

 

콘솔 창에 유저 아이디가 출력된다.

 

 

 


 

 

익명 로그인 만들기

Firebase Authentication에서, Sign-in method에서, 익명을 추가한다.

 

 

이전에 만들었던 FirebaseController 스크립트에 추가 코드를 붙인다.

public void SingIn()
{
    SignInAnonymous();
}
private Task SignInAnonymous()
{
    return auth.SignInAnonymouslyAsync().ContinueWithOnMainThread(task =>
    {
        if(task.IsFaulted)
        {
            Debug.Log("SignIn fail");
        }
        else if(task.IsCompleted)
        {
            Debug.Log("SignIn complete");
        }
    });
}

 

 

전체 코드

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Firebase.Auth;
using System.Threading.Tasks; //Task문법을 사용할 예정
using TMPro;
using Firebase.Extensions;
using System;

public class FirebaseController : MonoBehaviour
{
    private FirebaseAuth auth;
    private FirebaseUser user;
    void Start()
    {
        Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => //버전이 맞는지 체크
        {
            if(task.Result == Firebase.DependencyStatus.Available) //괜찮으면, 문제 없이 시작된다면,
            {
                FirebaseInit();
            }
            else //괜찮지 않다면
            {
                Debug.LogError("");
            }
        });
    }
    private void FirebaseInit()
    {
        auth = FirebaseAuth.DefaultInstance;
        auth.StateChanged += AuthStateChanged; //상태 변화가 있으면 함수를 불러와라
    }
    private void AuthStateChanged(object sender, EventArgs e)
    {
        FirebaseAuth senderAuth = sender as FirebaseAuth; //무슨 일이 생기면 sender와 EventArgs e가 작용한다.
        if(senderAuth != null) //유저가 있다면
        {
            user = senderAuth.CurrentUser;
            if(user != null) //유저가 무엇을 하려 하면(null이 아니면)
            {
                Debug.Log(user.UserId);
            }
        }
    }

    public void SingIn()
    {
        SignInAnonymous();
    }
    private Task SignInAnonymous()
    {
        return auth.SignInAnonymouslyAsync().ContinueWithOnMainThread(task =>
        {
            if(task.IsFaulted)
            {
                Debug.Log("SignIn fail");
            }
            else if(task.IsCompleted)
            {
                Debug.Log("SignIn complete");
            }
        });
    }
}

 

 

버튼에 함수를 매핑하고 그냥 로그인만 눌러도 SignIn complete 메시지와 함께 익명으로 유저가 만들어진 것을 볼 수 있다.

 

 


 

 

로그인 후 다른 씬 넘어가기

다른 씬을 만들고 Build Settings에 로그인 씬 하나와 다른 작업을 할 씬 하나를 넣는다. 이후 로그인을 하면 다른 씬을 불러오게 할 것이다.

 

 

그리고 FirebaseController 스크립트에서 네임스페이스를 추가한다.

using UnityEngine.SceneManagement;

 

 

SignInAnonymous 함수에 SceneManager.LoadScene(1); 추가

private Task SignInAnonymous()
{
    return auth.SignInAnonymouslyAsync().ContinueWithOnMainThread(task =>
    {
        if(task.IsFaulted)
        {
            Debug.Log("SignIn fail");
        }
        else if(task.IsCompleted)
        {
            Debug.Log("SignIn complete");
            SceneManager.LoadScene(1);
        }
    });
}

 

 

전체 스크립트

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Firebase.Auth;
using System.Threading.Tasks; //Task문법을 사용할 예정
using TMPro;
using Firebase.Extensions;
using System;
using UnityEngine.SceneManagement;

public class FirebaseController : MonoBehaviour
{
    private FirebaseAuth auth;
    private FirebaseUser user;
    void Start()
    {
        Firebase.FirebaseApp.CheckAndFixDependenciesAsync().ContinueWithOnMainThread(task => //버전이 맞는지 체크
        {
            if(task.Result == Firebase.DependencyStatus.Available) //괜찮으면, 문제 없이 시작된다면,
            {
                FirebaseInit();
            }
            else //괜찮지 않다면
            {
                Debug.LogError("");
            }
        });
    }
    private void FirebaseInit()
    {
        auth = FirebaseAuth.DefaultInstance;
        auth.StateChanged += AuthStateChanged; //상태 변화가 있으면 함수를 불러와라
    }
    private void AuthStateChanged(object sender, EventArgs e)
    {
        FirebaseAuth senderAuth = sender as FirebaseAuth; //무슨 일이 생기면 sender와 EventArgs e가 작용한다.
        if(senderAuth != null) //유저가 있다면
        {
            user = senderAuth.CurrentUser;
            if(user != null) //유저가 무엇을 하려 하면(null이 아니면)
            {
                Debug.Log(user.UserId);
            }
        }
    }

    public void SignIn()
    {
        SignInAnonymous();
    }
    private Task SignInAnonymous()
    {
        return auth.SignInAnonymouslyAsync().ContinueWithOnMainThread(task =>
        {
            if(task.IsFaulted)
            {
                Debug.Log("SignIn fail");
            }
            else if(task.IsCompleted)
            {
                Debug.Log("SignIn complete");
                SceneManager.LoadScene(1);
            }
        });
    }
}

 

 


 

 

데이터베이스

이전에 받았던 유니티 패키지 SDK 중에서 FirebaseDatabase.unitypackage를 import한다.

 

 

Realtime Database를 생성한다.

 

 

상단에 보이는 URL로 데이터베이스에 접근이 가능하다.

 

 

[Assets] - [StreamingAssets]폴더에 다시 한 번 josn파일을 다운받아 업데이트 시킨다.

 

 

이제 Firebase 웹 상에서 데이터베이스를 수정할 수 있다.

 

 

UI를 구성한 후 스크립트를 생성한다.

 

 

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Firebase.Database;
using TMPro;

public class DatabaseManager : MonoBehaviour
{
    public TMP_InputField nameInput;
    public TMP_InputField levelInput;
    public TMP_InputField goldInput;
    public TMP_Text action;

    public string name;
    public string level;
    public string gold;

    public class Data
    {
        public string level;
        public string gold;

        public Data(string level, string gold)
        {
            this.level = level;
            this.gold = gold;
        }
    }
    private DatabaseReference databaseReference;
    void Start()
    {
        databaseReference = FirebaseDatabase.DefaultInstance.RootReference; //실시간 데이터베이스 웹의 URL 부분이 Root
    }

    public void OnClickSave()
    {
        name = nameInput.text;
        level = levelInput.text;
        gold = goldInput.text;

        var data = new Data(level, gold);
        string jsonData = JsonUtility.ToJson(data);

        databaseReference.Child(name).SetRawJsonValueAsync(jsonData);

        action.text = "저장";
    }
}

 

 

스크립트를 GameObject에 넣고, InputField를 연결 한 후 InputField에 값을 입력해서 Save 버튼을 누르면 실시간 데이터베이스에 값이 입력된다.

 

 

실행 후 입력값을 입력하고 Save 버튼을 누르면,

444가 name이 되는 것이다.

gold와 level의 순서는 알파벳 순서로 결정된다.

728x90
반응형