Firebase Realtime Database에서 데이터를 가져올 때, 정렬 및 필터링 하는 방법을 파이어베이스 공식문서 Android에서 데이터 목록 다루기를 참고하여 정리해 본다.
Realtime Database 정렬
정렬은 다음과 같은 메서드를 제공한다.
- orderByChild() 지정된 하위 키 또는 중첩된 하위 경로의 값에 따라 결과를 정렬합니다.
- orderByKey() 하위 키에 따라 결과를 정렬합니다.
- orderByValue() 하위 값에 따라 결과를 정렬합니다.
테스트 JSON 데이터
테스트를 하기 위한 JSON 데이터는 다음과 같다.
{
"items" : {
"item1": {
"desc": "봉봉",
"title": "포도",
"category": "fruit",
"price": 2000,
"regdate" : 1744297200000
},
"item2": {
"desc": "우유",
"title": "바나나",
"category": "food",
"price": 4000,
"regdate" : 1744383600000
},
"item3": {
"desc": "제주",
"title": "감귤",
"category": "fruit",
"price": 2500,
"regdate" : 1744470000000
}
}
}
orderByChild
구조화된 데이터에 특정 필드를 지정하여 정렬 한다. 아래는 items의 각 item에 price로 정렬하여 데이터를 받아오는 코드 이다.
final dbRef = FirebaseDatabase.instance.ref().child('items');
final query = dbRef.orderByChild("price");
query.once().then((DatabaseEvent event) {
final items = <Item>[];
final itemlst = event.snapshot.children;
for (final item in itemlst) {
final value = item.value as Map;
print('${item.key} - ${value['title']} : ${value['price']}원');
}
});
결과는 다음과 같이 가격순으로 정렬되어 표시된다.
I/flutter (32319): item1 - 포도 : 2000원
I/flutter (32319): item3 - 감귤 : 2500원
I/flutter (32319): item2 - 바나나 : 4000원
orderByChild를 사용하면 지정 하위키를 포함하는 데이터가 다음과 같은 순서로 정렬된다.
- 지정 하위키 값이 null인 경우 우선 순위이다. 그 다음에는 false인 하위요소가 그 다음으로 정렬된다. 값이 여러개인 경우에는 key에 따라 사전순으로 정렬된다.
- 지정 하위키 값이 true인 하위 요소가 그 다음이고 값이 여러개인 경우 key에 따라 사전순으로 정렬된다.
- 숫자값이 있는 하위 요소가 그 다음이고 오름차순으로 정렬된다. 값이 여러개인 경우 key에 따라 사전순으로 정렬된다.
- 문자열 하위 요소는 사전순,오름차순으로 정렬된다. 값이 여러개인 경우 key에 따라 사전순으로 정렬된다.
- 마지막은 객체이며 키에 따라 사전순, 오름차순으로 정렬된다.
orderByKey
아이템의 키순으로 정렬한다. 아래는 키순으로 정렬하는 코드 이다.
final ref = FirebaseDatabase.instance.ref().child('items');
final query = ref.orderByKey();
query.once().then((event) {
final children = event.snapshot.children;
for (final item in children) {
final key = item.key;
final value = item.value as Map;
print('$key - ${value['title']}');
}
});
결과는 다음과 같이 아이템 키순으로 정렬되어 표시된다.
I/flutter ( 1508): item1 - 포도
I/flutter ( 1508): item2 - 바나나
I/flutter ( 1508): item3 - 감귤
orderByKey는 다음과 같은 순서로 정렬된다.
- 키가 32비트 정수로 파싱될 수 있는 하위요소, 오름차순으로 정렬된다.
- 키가 문자열 값인 하위요소, 오름차순(사전순)으로 정렬된다.
orderByValue
하위값에 따라 정렬된다. orderByValue는 값이 단순해야하므로(위 JSON 데이터처럼 복잡한 MAP구조는 안됨) 해당 테스트는 아래 JSON 데이터를 이용했다.
{
"items" : {
"item1": 10,
"item2": 20,
"item3": 1
}
}
값에 따라 정렬하는 코드는 다음과 같다.
final ref = FirebaseDatabase.instance.ref().child('items');
final query = ref.orderByValue();
query.once().then((event) {
final children = event.snapshot.children;
for (final item in children) {
final key = item.key;
final value = item.value;
print('$key - $value');
}
});
결과는 다음과 같이 값에 따라 정렬되어 표시된다.
I/flutter ( 3142): item3 - 1
I/flutter ( 3142): item1 - 10
I/flutter ( 3142): item2 - 20
orderByValue의 정렬방식은 orderByChild과 동일하며 지정한 하위키의 값대신 노드 값이 사용된다는 것만 다르다.
Realtime Database 필터링
필터링을 사용하면 제한 또는 범위 메서드를 정렬 기준 메서드와 조합하여 쿼리를 작성할 수 있다. 정렬기준메서드와 달리 여러 함수를 동시에 사용가능하다(ex: startAt, endAt을 함께 조합해서 사용가능)
- limitToFirst() 정렬된 결과 목록의 시작 부터 반환할 최대 항목 개수 설정.
- limitToLast() 정렬된 결과 목록의 끝 부터 반환할 최대 항목 개수 설정.
- startAt() 선택한 정렬 기준 메서드에 따라 지정된 키 or 값보다 크거나 같은 항목 반환.
- startAfter() 선택한 정렬 기준 메서드에 따라 지정된 키 or 값보다 큰 항목 반환.
- endAt() 선택한 정렬 기준 메서드에 따라 지정된 키 or 값보다 작거나 같은 항목 반환.
- endBefore() 선택한 정렬 기준 메서드에 따라 지정된 키 or 값보다 작은 항목 반환.
- equalTo() 선택한 정렬 기준 메서드에 따라 지정된 키 or 값과 동일한 항목 반환.
위 orderByChild 예제에서 값이 2,500원인 아이템만 가져오는 코드는 다음과 같다.
final query = dbRef.orderByChild("price").equalTo(2500);
상위 2개의 아이템만 가져오는 코드는 다음과 같다.
final query = dbRef.orderByChild("price").limitToFirst(2);