데이터베이스 참조 가져오기
데이터베이스에서 데이터를 읽거나 쓰려면 DatabaseReference
인스턴스가 필요합니다.
DatabaseReference ref = FirebaseDatabase.instance.ref();
목록 읽기 및 쓰기
데이터 목록에 추가
다중 사용자 응용 프로그램의 목록에 데이터를 추가하려면 push()
메서드를 사용합니다. push()
메서드는 지정된 Firebase 참조에 새 하위 항목이 추가될 때마다 고유 키를 생성합니다. 목록의 각 새 요소에 대해 이러한 자동 생성 키를 사용하여 여러 클라이언트가 쓰기 충돌 없이 같은 위치에 자식을 동시에 추가할 수 있습니다. push()
에 의해 생성된 고유 키는 타임스탬프를 기반으로 하므로 목록 항목은 자동으로 시간순으로 정렬됩니다.
push()
메서드에서 반환된 새 데이터에 대한 참조를 사용하여 자식의 자동 생성 키 값을 가져오거나 자식에 대한 데이터를 설정할 수 있습니다. push()
참조의 .key
속성에는 자동 생성된 키가 포함되어 있습니다.
이러한 자동 생성 키를 사용하여 데이터 구조 병합을 단순화할 수 있습니다. 자세한 내용은 데이터 팬아웃 예를 참조하세요.
예를 들어, push()
는 소셜 애플리케이션의 게시물 목록에 새 게시물을 추가하는 데 사용할 수 있습니다.
DatabaseReference postListRef = FirebaseDatabase.instance.ref("posts");
DatabaseReference newPostRef = postListRef.push();
newPostRef.set({
// ...
});
자식 이벤트 수신
자식 이벤트는 push()
메서드를 통해 추가된 새 자식 또는 update()
메서드를 통해 자식이 업데이트되는 등의 작업에서 노드의 자식에게 발생하는 특정 작업에 대한 응답으로 트리거됩니다.
이벤트 | 일반적인 사용법 |
---|---|
onChildAdded | 항목 목록을 검색하거나 항목 목록에 대한 추가 사항을 수신합니다. 이 이벤트는 각 기존 자식에 대해 한 번 트리거된 다음 지정된 경로에 새 자식이 추가될 때마다 다시 트리거됩니다. 리스너는 새 하위 데이터가 포함된 스냅샷을 전달합니다. |
onChildChanged | 목록의 항목에 대한 변경 사항을 듣습니다. 이 이벤트는 자식 노드가 수정될 때마다 트리거됩니다. 여기에는 자식 노드의 자손에 대한 모든 수정 사항이 포함됩니다. 이벤트 리스너에 전달된 스냅샷에는 자식에 대한 업데이트된 데이터가 포함됩니다. |
onChildRemoved | 목록에서 제거되는 항목을 듣습니다. 이 이벤트는 직계 자식이 제거될 때 트리거됩니다. 콜백 블록에 전달된 스냅샷에는 제거된 자식에 대한 데이터가 포함됩니다. |
onChildMoved | 정렬된 목록에서 항목 순서의 변경 사항을 수신합니다. onChildMoved 이벤트는 항상 항목의 주문을 변경한 onChildChanged 이벤트를 따릅니다(현재 order-by 방법 기반). |
이들 각각은 데이터베이스의 특정 노드에 대한 변경 사항을 수신 대기하는 데 유용할 수 있습니다. 예를 들어 소셜 블로깅 앱은 아래와 같이 게시물 댓글의 활동을 모니터링하기 위해 이러한 방법을 함께 사용할 수 있습니다.
final commentsRef = FirebaseDatabase.instance.ref("post-comments/$postId");
commentsRef.onChildAdded.listen((event) {
// A new comment has been added, so add it to the displayed list.
});
commentsRef.onChildChanged.listen((event) {
// A comment has changed; use the key to determine if we are displaying this
// comment and if so displayed the changed comment.
});
commentsRef.onChildRemoved.listen((event) {
// A comment has been removed; use the key to determine if we are displaying
// this comment and if so remove it.
});
가치 이벤트 수신
자식 이벤트를 수신하는 것이 데이터 목록을 읽는 데 권장되는 방법이지만 목록 참조에서 값 이벤트를 수신하는 것이 유용한 상황이 있습니다.
value
리스너를 데이터 목록에 연결하면 전체 데이터 목록이 단일 스냅샷으로 반환되며 이 스냅샷은 루프를 통해 개별 하위 항목에 액세스할 수 있습니다.
쿼리에 대해 일치하는 항목이 하나만 있는 경우에도 스냅샷은 여전히 목록입니다. 그것은 단지 하나의 항목을 포함합니다. 항목에 액세스하려면 결과를 반복해야 합니다.
myTopPostsQuery.onValue.listen((event) {
for (final child in event.snapshot.children) {
// Handle the post.
}
}, onError: (error) {
// Error.
});
이 패턴은 추가 자식 추가 이벤트를 수신 대기하는 대신 단일 작업으로 목록의 모든 자식을 가져오려는 경우에 유용할 수 있습니다.
데이터 정렬 및 필터링
Query
클래스를 사용하여 키, 값 또는 자식 값으로 정렬된 데이터를 검색할 수 있습니다. 정렬된 결과를 특정 수의 결과 또는 키 또는 값 범위로 필터링할 수도 있습니다.
데이터 정렬
정렬된 데이터를 검색하려면 우선 순위 지정 방법 중 하나를 지정하여 결과가 정렬되는 방식을 결정합니다.
방법 | 용법 |
---|---|
orderByChild() | 지정된 자식 키 또는 중첩된 자식 경로의 값으로 결과를 정렬합니다. | orderByKey() | 자식 키로 결과를 정렬합니다. |
orderByValue() | 자식 값으로 결과를 정렬합니다. |
한 번에 하나 의 주문 방식만 사용할 수 있습니다. 동일한 쿼리에서 order-by 메서드를 여러 번 호출하면 오류가 발생합니다.
다음 예는 별 수를 기준으로 정렬된 사용자의 상위 게시물 목록을 검색하는 방법을 보여줍니다.
final myUserId = FirebaseAuth.instance.currentUser?.uid;
final topUserPostsRef = FirebaseDatabase.instance
.ref("user-posts/$myUserId")
.orderByChild("starCount");
이것은 자식 리스너 와 결합될 때 각 게시물이 받은 별 수로 정렬된 사용자 ID를 기반으로 데이터베이스 경로의 사용자 게시물과 클라이언트를 동기화하는 쿼리를 정의합니다. ID를 인덱스 키로 사용하는 이 기술을 데이터 팬아웃이라고 합니다. 자세한 내용은 데이터베이스 구조화 에서 읽을 수 있습니다.
orderByChild()
메서드에 대한 호출은 결과를 정렬할 하위 키를 지정합니다. 이 경우 게시물은 해당 "starCount"
하위 항목의 값을 기준으로 정렬됩니다. 다음과 같은 데이터가 있는 경우 쿼리를 중첩된 자식별로 정렬할 수도 있습니다.
"posts": {
"ts-functions": {
"metrics": {
"views" : 1200000,
"likes" : 251000,
"shares": 1200,
},
"title" : "Why you should use TypeScript for writing Cloud Functions",
"author": "Doug",
},
"android-arch-3": {
"metrics": {
"views" : 900000,
"likes" : 117000,
"shares": 144,
},
"title" : "Using Android Architecture Components with Firebase Realtime Database (Part 3)",
"author": "Doug",
}
},
이 경우 orderByChild()
호출에서 중첩된 자식에 대한 상대 경로를 지정하여 metrics
키 아래에 중첩된 값으로 목록 요소를 정렬할 수 있습니다.
final mostViewedPosts =
FirebaseDatabase.instance.ref('posts').orderByChild('metrics/views');
다른 데이터 유형이 정렬되는 방식에 대한 자세한 내용은 쿼리 데이터가 정렬되는 방식 을 참조하세요.
데이터 필터링
데이터를 필터링하기 위해 쿼리를 구성할 때 제한 또는 범위 방법을 순서별 방법과 결합할 수 있습니다.
방법 | 용법 |
---|---|
limitToFirst() | 정렬된 결과 목록의 시작 부분부터 반환할 최대 항목 수를 설정합니다. |
limitToLast() | 정렬된 결과 목록의 끝에서 반환할 최대 항목 수를 설정합니다. |
startAt() | 선택한 order-by 방법에 따라 지정된 키 또는 값보다 크거나 같은 항목을 반환합니다. |
startAfter() | 선택한 order-by 방법에 따라 지정된 키 또는 값보다 큰 항목을 반환합니다. |
endAt() | 선택한 order-by 방법에 따라 지정된 키 또는 값보다 작거나 같은 항목을 반환합니다. |
endBefore() | 선택한 order-by 방법에 따라 지정된 키 또는 값보다 작은 항목을 반환합니다. |
equalTo() | 선택한 order-by 방법에 따라 지정된 키 또는 값과 동일한 항목을 반환합니다. |
order-by 방법과 달리 여러 제한 또는 범위 기능을 결합할 수 있습니다. 예를 들어 startAt()
및 endAt()
메서드를 결합하여 지정된 값 범위로 결과를 제한할 수 있습니다.
결과 수 제한
limitToFirst()
및 limitToLast()
메서드를 사용하여 주어진 이벤트에 대해 동기화할 최대 자식 수를 설정할 수 있습니다. 예를 들어 limitToFirst()
를 사용하여 제한을 100으로 설정하면 처음에는 최대 100개의 onChildAdded
이벤트만 수신합니다. Firebase 데이터베이스에 저장된 항목이 100개 미만인 경우 각 항목에 대해 onChildAdded
이벤트가 발생합니다.
항목이 변경되면 쿼리를 입력하는 항목에 대해 onChildAdded
이벤트를 수신하고 쿼리에서 onChildRemoved
항목에 대해 onChildRemoved 이벤트를 수신하여 총 수가 100을 유지합니다.
다음 예제에서는 예제 블로깅 앱이 모든 사용자의 가장 최근 게시물 100개 목록을 검색하는 쿼리를 정의하는 방법을 보여줍니다.
final recentPostsRef = FirebaseDatabase.instance.ref('posts').limitToLast(100);
이 예제는 연결된 리스너 가 있어야 하는 데이터를 실제로 동기화하기 위해 쿼리만 정의합니다.
키 또는 값으로 필터링
startAt()
, startAfter()
, endAt()
, endBefore()
및 equalTo()
를 사용하여 쿼리에 대한 임의의 시작, 끝 및 등가 지점을 선택할 수 있습니다. 이것은 데이터에 페이지를 매기거나 특정 값을 가진 자식이 있는 항목을 찾는 데 유용할 수 있습니다.
쿼리 데이터가 정렬되는 방식
이 섹션에서는 Query
클래스의 각 order-by 메소드별로 데이터를 정렬하는 방법을 설명합니다.
orderByChild
orderByChild()
를 사용할 때 지정된 자식 키가 포함된 데이터는 다음과 같이 정렬됩니다.
- 지정된 자식 키에 대해
null
값을 가진 자식이 먼저 옵니다. - 지정된 자식 키에 대해 값이
false
인 자식이 다음에 옵니다. 여러 자식의 값이false
이면 키를 기준으로 사전순 으로 정렬됩니다. - 지정된 자식 키에 대해 값이
true
인 자식이 다음에 옵니다. 여러 자식의 값이true
키를 기준으로 사전순으로 정렬됩니다. - 숫자 값이 있는 자식이 오름차순으로 정렬되어 다음에 옵니다. 여러 자식이 지정된 자식 노드에 대해 동일한 숫자 값을 갖는 경우 키를 기준으로 정렬됩니다.
- 문자열은 숫자 다음에 오고 사전순으로 오름차순으로 정렬됩니다. 여러 자식이 지정된 자식 노드에 대해 동일한 값을 갖는 경우 키를 기준으로 사전순으로 정렬됩니다.
- 객체는 마지막에 오며 키를 기준으로 사전순으로 오름차순으로 정렬됩니다.
orderByKey
orderByKey()
를 사용하여 데이터를 정렬할 때 데이터는 키를 기준으로 오름차순으로 반환됩니다.
- 32비트 정수로 구문 분석할 수 있는 키가 있는 자식이 먼저 오며 오름차순으로 정렬됩니다.
- 문자열 값을 키로 사용하는 자식이 다음으로 오고 사전순으로 오름차순으로 정렬됩니다.
orderByValue
orderByValue()
를 사용할 때 자식은 값에 따라 정렬됩니다. 순서 지정 기준은 지정된 자식 키 값 대신 노드 값이 사용된다는 점을 제외하고 orderByChild()
와 동일합니다.
수신기 분리
콜백은 Firebase 데이터베이스 참조에서 off()
메서드를 호출하여 제거됩니다.
off()
에 매개변수로 전달하여 단일 리스너를 제거할 수 있습니다. 인수가 없는 위치에서 off()
를 호출하면 해당 위치의 모든 리스너가 제거됩니다.
부모 리스너에서 off()
를 호출해도 자식 노드에 등록된 리스너는 자동으로 제거되지 않습니다. 콜백을 제거하려면 자식 리스너에서도 off()
를 호출해야 합니다.