데이터 검색

이 문서에서는 데이터 검색의 기초와 함께 Firebase 데이터를 정렬 및 필터링하는 방법을 설명합니다.

시작하기 전에

Realtime Database을 사용하려면 먼저 다음 작업을 해야 합니다.

  • Unity 프로젝트를 등록하고 Firebase를 사용하도록 구성합니다.

    • Unity 프로젝트에서 현재 Firebase를 사용하고 있다면 이미 등록되어 Firebase용으로 구성된 것입니다.

    • Unity 프로젝트가 없는 경우 샘플 앱을 다운로드하면 됩니다.

  • Firebase Unity SDK(특히 FirebaseDatabase.unitypackage)를 Unity 프로젝트에 추가합니다.

Unity 프로젝트에 Firebase를 추가할 때 Firebase Console 및 열려 있는 Unity 프로젝트 모두에서 작업을 수행해야 합니다. 예를 들어 Console에서 Firebase 구성 파일을 다운로드한 후 이 파일을 Unity 프로젝트로 이동하는 작업이 필요합니다.

데이터 검색

Firebase 데이터를 검색하려면 GetValueAsync()를 한 번 호출하거나 FirebaseDatabase 참조에서 이벤트에 연결합니다. 이벤트 리스너는 데이터의 초기 상태를 확인할 때 한 번 호출된 후 데이터가 변경될 때마다 다시 호출됩니다.

DatabaseReference 가져오기

데이터베이스에서 데이터를 읽으려면 DatabaseReference의 인스턴스가 필요합니다.

using Firebase;
using Firebase.Database;
using Firebase.Extensions.TaskExtension; // for ContinueWithOnMainThread

public class MyScript: MonoBehaviour {
  void Start() {
    // Get the root reference location of the database.
    DatabaseReference reference = FirebaseDatabase.DefaultInstance.RootReference;
  }
}

데이터 한 번 읽기

GetValueAsync 메서드를 사용하여 지정된 경로에서 콘텐츠의 정적 스냅샷을 읽을 수 있습니다. 작업 결과에 하위 데이터 등 해당 위치의 모든 데이터를 포함하는 스냅샷이 포함됩니다. 데이터가 없을 때 반환되는 스냅샷은 null입니다.

    FirebaseDatabase.DefaultInstance
      .GetReference("Leaders")
      .GetValueAsync().ContinueWithOnMainThread(task =&gt {
        if (task.IsFaulted) {
          // Handle the error...
        }
        else if (task.IsCompleted) {
          DataSnapshot snapshot = task.Result;
          // Do something with snapshot...
        }
      });

이벤트 수신 대기

이벤트 리스너를 추가해 데이터 변경 사항을 구독할 수 있습니다.

이벤트 일반적인 용도
ValueChanged 경로의 전체 내용에 대한 변경을 읽고 수신 대기합니다.
ChildAdded 항목 목록을 검색하거나 항목 목록에 대한 추가를 수신 대기합니다. ChildChangedChildRemoved와 함께 사용하여 목록의 변경을 모니터링할 수 있습니다.
ChildChanged 목록의 항목에 대한 변경사항을 수신 대기합니다. ChildAddedChildRemoved와 함께 사용하여 목록의 변경을 모니터링합니다.
ChildRemoved 목록의 항목 삭제를 수신 대기합니다. ChildAddedChildChanged와 함께 사용하여 목록의 변경을 모니터링합니다.
ChildMoved 순서가 지정된 목록의 항목 순서 변경사항을 수신 대기합니다. ChildMoved 이벤트는 항상 현재의 정렬 기준에 따라 항목 순서를 변경하도록 한 ChildChanged 이벤트 뒤에 나옵니다.

ValueChanged 이벤트

ValueChanged 이벤트를 사용하여 지정된 경로의 콘텐츠 변경사항을 구독할 수 있습니다. 이 이벤트는 리스너가 연결될 때 한 번 호출된 후 하위 데이터를 포함한 데이터가 변경될 때마다 다시 호출됩니다. 하위 데이터를 포함하여 해당 위치의 모든 데이터를 포함하는 스냅샷이 이벤트 콜백에 전달됩니다. 데이터가 없을 때 반환되는 스냅샷은 null입니다.

다음 예시에서는 데이터베이스에서 리더보드 점수를 검색하는 게임을 보여 줍니다.

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders")
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

ValueChangedEventArgs는 이벤트 발생 시점에 데이터베이스에서 지정된 위치에 있던 데이터를 포함하는 DataSnapshot을 포함합니다. 스냅샷에서 Value를 호출하면 데이터를 나타내는 Dictionary<string, object>가 반환됩니다. 해당 위치에 데이터가 없는 경우 Value를 호출하면 null이 반환됩니다.

이 예시에서 읽기가 취소되었는지 확인하기 위해 args.DatabaseError도 검사합니다. 예를 들어 클라이언트에 Firebase 데이터베이스 위치에서 데이터를 읽을 권한이 없으면 읽기가 취소될 수 있습니다. DatabaseError는 실패 이유를 나타냅니다.

이후에 동일한 경로를 갖는 DatabaseReference를 사용하여 이벤트를 구독 취소할 수 있습니다. DatabaseReference 인스턴스는 임의의 경로와 쿼리에 액세스하는 데 사용되는 임시 수단으로 간주할 수 있습니다.

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders")
        .ValueChanged -= HandleValueChanged; // unsubscribe from ValueChanged.
    }

하위 이벤트

하위 이벤트는 노드의 하위 항목에서 발생하는 특정 작업에 대응하여 트리거됩니다. 하위 항목이 Push() 메서드를 통해 새로 추가되거나 UpdateChildrenAsync() 메서드를 통해 업데이트되는 경우가 그 예시입니다. 이러한 메서드는 데이터베이스의 특정 노드에 대한 변경 사항을 수신 대기하는 데 유용할 수 있습니다. 예를 들어 게임은 아래와 같이 이러한 메서드를 함께 사용하여 게임 세션의 댓글 활동을 모니터링할 수 있습니다.

      var ref = FirebaseDatabase.DefaultInstance
      .GetReference("GameSessionComments");

      ref.ChildAdded += HandleChildAdded;
      ref.ChildChanged += HandleChildChanged;
      ref.ChildRemoved += HandleChildRemoved;
      ref.ChildMoved += HandleChildMoved;
    }

    void HandleChildAdded(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildChanged(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildRemoved(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

    void HandleChildMoved(object sender, ChildChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

ChildAdded 이벤트는 일반적으로 Firebase 데이터베이스의 항목 목록을 검색하는 데 사용됩니다. ChildAdded 이벤트는 기존 하위 항목마다 한 번씩 발생한 후 지정된 경로에 하위 항목이 새로 추가될 때마다 다시 발생합니다. 리스너에는 새 하위 항목의 데이터를 포함하는 스냅샷이 전달됩니다.

ChildChanged 이벤트는 하위 노드가 수정될 때마다 발생합니다. 여기에는 하위 노드의 하위 항목에 대한 수정이 포함됩니다. 이 이벤트는 일반적으로 ChildAddedChildRemoved 이벤트와 함께 항목 목록의 변경에 대응하는 데 사용됩니다. 이벤트 리스너에 전달되는 스냅샷에는 하위 항목의 업데이트된 데이터가 포함됩니다.

ChildRemoved 이벤트는 바로 아래 하위 항목이 삭제될 때 트리거됩니다. 이 이벤트는 일반적으로 ChildAddedChildChanged 콜백과 함께 사용됩니다. 이벤트 콜백에 전달되는 스냅샷에는 삭제된 하위 항목의 데이터가 포함됩니다.

하위 항목이 재정렬되는 업데이트 때문에 ChildMoved 이벤트가 발생할 때마다 ChildChanged 이벤트가 트리거됩니다. 이 이벤트는 OrderByChild 또는 OrderByValue로 정렬된 데이터에 사용됩니다.

데이터 정렬 및 필터링

Realtime DatabaseQuery 클래스를 사용하여 키, 값 또는 하위 요소 값으로 정렬된 데이터를 검색할 수 있습니다. 정렬된 결과를 특정 개수로 필터링하거나 키 또는 값 범위에 따라 필터링할 수도 있습니다.

데이터 정렬

정렬된 데이터를 검색하려면 우선 정렬 기준 메서드 중 하나를 지정하여 결과를 어떤 순서로 정렬할지 결정합니다.

메서드 사용
OrderByChild() 지정된 하위 키의 값에 따라 결과를 정렬합니다.
OrderByKey() 하위 키에 따라 결과를 정렬합니다.
OrderByValue() 하위 값에 따라 결과를 정렬합니다.

정렬 기준 메서드는 한번에 하나만 사용할 수 있습니다. 한 쿼리에서 정렬 기준 메서드를 여러 번 호출하면 오류가 발생합니다.

다음 예에서는 점수별로 정렬된 점수 리더보드를 구독하는 방법을 보여 줍니다.

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders").OrderByChild("score")
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

여기에서는 쿼리를 정의하고 Valuechanged 이벤트 리스너와 함께 사용하여 데이터베이스의 리더보드를 각 항목의 점수에 따라 정렬한 결과를 클라이언트와 동기화합니다. 데이터를 효율적으로 구조화하는 방법에 대한 자세한 내용은 데이터베이스 구조화를 참조하세요.

OrderByChild() 메서드를 호출할 때는 결과를 정렬하는 기준이 될 하위 키를 지정합니다. 여기에서는 결과가 각 하위의 "score" 값에 따라 정렬됩니다. 다른 데이터 유형을 정렬하는 방법에 대한 자세한 내용은 쿼리 데이터정렬 방식을 참조하세요.

데이터 필터링

데이터를 필터링하려면 제한 또는 범위 메서드를 정렬 기준 메서드와 조합하여 쿼리를 작성합니다.

메서드 사용
LimitToFirst() 정렬된 결과 목록의 시작 부분부터 반환할 최대 항목 수를 설정합니다.
LimitToLast() 정렬된 결과 목록에서 맨 끝부터 반환할 최대 항목 개수를 설정합니다.
StartAt() 선택한 정렬 기준 메서드에 따라 지정된 키 또는 값보다 크거나 같은 항목을 반환합니다.
EndAt() 선택한 정렬 기준 메서드에 따라 지정된 키 또는 값보다 작거나 같은 항목을 반환합니다.
EqualTo() 선택한 정렬 기준 메서드에 따라 지정된 키 또는 값과 동일한 항목을 반환합니다.

정렬 기준 메서드와 달리 여러 제한 또는 범위 함수를 결합할 수 있습니다. 예를 들어 StartAt()EndAt() 메서드를 조합하여 결과를 지정된 값 범위로 제한할 수 있습니다.

쿼리에 일치하는 항목이 단 하나인 경우라도 스냅샷은 목록으로 표시됩니다. 항목이 하나만 있을 뿐입니다.

결과 수 제한

LimitToFirst()LimitToLast() 메서드를 사용하여 특정 콜백에서 동기화할 하위 요소의 최대 개수를 설정할 수 있습니다. 예를 들어 LimitToFirst()를 사용하여 제한을 100개로 설정하면 처음에 최대 100개의 ChildAdded 콜백만 수신합니다. Firebase 데이터베이스에 저장된 항목이 100개 미만이면 각 항목에 ChildAdded 콜백이 호출됩니다.

항목이 변경됨에 따라 쿼리에 새로 포함되는 항목에 대해 ChildAdded 콜백, 쿼리에서 제외되는 항목에 대해 ChildRemoved 콜백이 수신되며 총 개수는 100개로 유지됩니다.

예를 들어 다음 코드는 리더보드에서 최고 점수를 반환합니다.

      FirebaseDatabase.DefaultInstance
        .GetReference("Leaders").OrderByChild("score").LimitToLast(1)
        .ValueChanged += HandleValueChanged;
    }

    void HandleValueChanged(object sender, ValueChangedEventArgs args) {
      if (args.DatabaseError != null) {
        Debug.LogError(args.DatabaseError.Message);
        return;
      }
      // Do something with the data in args.Snapshot
    }

키 또는 값으로 필터링

StartAt(), EndAt(), EqualTo()를 사용하여 쿼리의 시작, 종료, 동일 지점을 임의로 선택할 수 있습니다. 이 메서드는 특정 값을 갖는 하위 요소로 데이터를 페이지로 나누거나 항목을 찾는 데 유용합니다.

쿼리 데이터 정렬 방법

이 섹션에서는 Query 클래스의 각 정렬 기준 메서드에 따라 데이터를 정렬하는 방법을 설명합니다.

OrderByChild

OrderByChild()를 사용하면 지정된 하위 키를 포함하는 데이터가 다음과 같이 정렬됩니다.

  1. 지정된 하위 키의 값이 null인 하위 요소가 맨 처음에 옵니다.
  2. 지정된 하위 키의 값이 false인 하위 요소가 그다음에 옵니다. 값이 false인 하위 요소가 여러 개인 경우 키에 따라 사전순으로 정렬됩니다.
  3. 지정된 하위 키의 값이 true인 하위 요소가 그다음에 옵니다. 값이 true인 하위 요소가 여러 개인 경우 키에 따라 사전순으로 정렬됩니다.
  4. 숫자 값이 있는 하위 요소가 그다음에 나오며 오름차순으로 정렬됩니다. 지정된 하위 노드의 숫자 값이 동일한 하위 요소가 여러 개면 키에 따라 정렬됩니다.
  5. 숫자 다음에는 문자열이 나오며 사전순, 오름차순으로 정렬됩니다. 지정된 하위 노드의 값이 동일한 하위 요소가 여러 개면 키에 따라 사전순으로 정렬됩니다.
  6. 마지막으로 객체가 나오며 키에 따라 사전순, 오름차순으로 정렬됩니다.

OrderByKey

OrderByKey()를 사용하여 데이터를 정렬하면 데이터가 오름차순(키 기준)으로 반환됩니다.

  1. 키가 32비트 정수로 파싱될 수 있는 하위 요소가 맨 처음에 나오며 오름차순으로 정렬됩니다.
  2. 키가 문자열 값인 하위 요소가 그다음에 나오며 오름차순(사전순)으로 정렬됩니다.

OrderByValue

OrderByValue()를 사용하면 하위 요소가 값에 따라 정렬됩니다. 정렬 기준은 OrderByChild()와 동일하며, 지정된 하위 키의 값 대신 노드의 값이 사용된다는 점이 다릅니다.