Skip to content

Commit 65d9bb7

Browse files
authored
refactor(database, android): simplify query handling by extracting queryFromModifiers method (#18221)
1 parent 39e5a80 commit 65d9bb7

2 files changed

Lines changed: 29 additions & 258 deletions

File tree

packages/firebase_database/firebase_database/android/src/main/kotlin/io/flutter/plugins/firebase/database/FirebaseDatabasePlugin.kt

Lines changed: 11 additions & 244 deletions
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,16 @@ class FirebaseDatabasePlugin :
141141
@Suppress("UNCHECKED_CAST")
142142
private fun getQuery(arguments: Map<String, Any>): Query {
143143
val ref = getReference(arguments)
144-
val modifiers = arguments[Constants.MODIFIERS] as List<Map<String, Any>>
145-
return QueryBuilder(ref, modifiers).build()
144+
val modifiers = arguments[Constants.MODIFIERS] as List<Map<String, Any?>>
145+
return queryFromModifiers(ref, modifiers)
146146
}
147147

148+
/** Applies [modifiers]. */
149+
private fun queryFromModifiers(
150+
reference: DatabaseReference,
151+
modifiers: List<Map<String, Any?>>,
152+
): Query = QueryBuilder(reference, modifiers).build()
153+
148154
private fun goOnline(arguments: Map<String, Any>): Task<Void> {
149155
val taskCompletionSource = TaskCompletionSource<Void>()
150156

@@ -844,84 +850,7 @@ class FirebaseDatabasePlugin :
844850
Log.d("FirebaseDatabase", "🔍 Kotlin: Setting up query observe for path=${request.path}")
845851
val database = getDatabaseFromPigeonApp(app)
846852
val reference = database.getReference(request.path)
847-
848-
// Apply query modifiers if any
849-
var query: com.google.firebase.database.Query = reference
850-
// Note: no hasOrderModifier needed — Android SDK defaults to PriorityIndex
851-
// when no orderBy is specified, so cursors work without an explicit orderBy.
852-
853-
for (modifier in request.modifiers) {
854-
when (modifier["type"] as String) {
855-
"orderBy" -> {
856-
when (modifier["name"] as String) {
857-
"orderByChild" -> {
858-
query = query.orderByChild(modifier["path"] as String)
859-
}
860-
"orderByKey" -> {
861-
query = query.orderByKey()
862-
}
863-
"orderByValue" -> {
864-
query = query.orderByValue()
865-
}
866-
"orderByPriority" -> {
867-
query = query.orderByPriority()
868-
}
869-
}
870-
}
871-
"cursor" -> {
872-
when (modifier["name"] as String) {
873-
"startAt" -> {
874-
val value = modifier["value"]
875-
val key = modifier["key"] as String?
876-
query = when (value) {
877-
is Boolean -> if (key == null) query.startAt(value) else query.startAt(value, key)
878-
is Number -> if (key == null) query.startAt(value.toDouble()) else query.startAt(value.toDouble(), key)
879-
else -> if (key == null) query.startAt(value.toString()) else query.startAt(value.toString(), key)
880-
}
881-
}
882-
"startAfter" -> {
883-
val value = modifier["value"]
884-
val key = modifier["key"] as String?
885-
query = when (value) {
886-
is Boolean -> if (key == null) query.startAfter(value) else query.startAfter(value, key)
887-
is Number -> if (key == null) query.startAfter(value.toDouble()) else query.startAfter(value.toDouble(), key)
888-
else -> if (key == null) query.startAfter(value.toString()) else query.startAfter(value.toString(), key)
889-
}
890-
}
891-
"endAt" -> {
892-
val value = modifier["value"]
893-
val key = modifier["key"] as String?
894-
query = when (value) {
895-
is Boolean -> if (key == null) query.endAt(value) else query.endAt(value, key)
896-
is Number -> if (key == null) query.endAt(value.toDouble()) else query.endAt(value.toDouble(), key)
897-
else -> if (key == null) query.endAt(value.toString()) else query.endAt(value.toString(), key)
898-
}
899-
}
900-
"endBefore" -> {
901-
val value = modifier["value"]
902-
val key = modifier["key"] as String?
903-
query = when (value) {
904-
is Boolean -> if (key == null) query.endBefore(value) else query.endBefore(value, key)
905-
is Number -> if (key == null) query.endBefore(value.toDouble()) else query.endBefore(value.toDouble(), key)
906-
else -> if (key == null) query.endBefore(value.toString()) else query.endBefore(value.toString(), key)
907-
}
908-
}
909-
}
910-
}
911-
"limit" -> {
912-
when (modifier["name"] as String) {
913-
"limitToFirst" -> {
914-
val value = (modifier["limit"] as Number).toInt()
915-
query = query.limitToFirst(value)
916-
}
917-
"limitToLast" -> {
918-
val value = (modifier["limit"] as Number).toInt()
919-
query = query.limitToLast(value)
920-
}
921-
}
922-
}
923-
}
924-
}
853+
val query = queryFromModifiers(reference, request.modifiers)
925854

926855
// Generate a unique channel name
927856
val channelName = "firebase_database_query_${System.currentTimeMillis()}_${request.path.hashCode()}"
@@ -947,84 +876,7 @@ class FirebaseDatabasePlugin :
947876
try {
948877
val database = getDatabaseFromPigeonApp(app)
949878
val reference = database.getReference(request.path)
950-
951-
// Apply query modifiers if any
952-
var query: com.google.firebase.database.Query = reference
953-
// Note: no hasOrderModifier needed — Android SDK defaults to PriorityIndex
954-
// when no orderBy is specified, so cursors work without an explicit orderBy.
955-
956-
for (modifier in request.modifiers) {
957-
when (modifier["type"] as String) {
958-
"orderBy" -> {
959-
when (modifier["name"] as String) {
960-
"orderByChild" -> {
961-
query = query.orderByChild(modifier["path"] as String)
962-
}
963-
"orderByKey" -> {
964-
query = query.orderByKey()
965-
}
966-
"orderByValue" -> {
967-
query = query.orderByValue()
968-
}
969-
"orderByPriority" -> {
970-
query = query.orderByPriority()
971-
}
972-
}
973-
}
974-
"cursor" -> {
975-
when (modifier["name"] as String) {
976-
"startAt" -> {
977-
val value = modifier["value"]
978-
val key = modifier["key"] as String?
979-
query = when (value) {
980-
is Boolean -> if (key == null) query.startAt(value) else query.startAt(value, key)
981-
is Number -> if (key == null) query.startAt(value.toDouble()) else query.startAt(value.toDouble(), key)
982-
else -> if (key == null) query.startAt(value.toString()) else query.startAt(value.toString(), key)
983-
}
984-
}
985-
"startAfter" -> {
986-
val value = modifier["value"]
987-
val key = modifier["key"] as String?
988-
query = when (value) {
989-
is Boolean -> if (key == null) query.startAfter(value) else query.startAfter(value, key)
990-
is Number -> if (key == null) query.startAfter(value.toDouble()) else query.startAfter(value.toDouble(), key)
991-
else -> if (key == null) query.startAfter(value.toString()) else query.startAfter(value.toString(), key)
992-
}
993-
}
994-
"endAt" -> {
995-
val value = modifier["value"]
996-
val key = modifier["key"] as String?
997-
query = when (value) {
998-
is Boolean -> if (key == null) query.endAt(value) else query.endAt(value, key)
999-
is Number -> if (key == null) query.endAt(value.toDouble()) else query.endAt(value.toDouble(), key)
1000-
else -> if (key == null) query.endAt(value.toString()) else query.endAt(value.toString(), key)
1001-
}
1002-
}
1003-
"endBefore" -> {
1004-
val value = modifier["value"]
1005-
val key = modifier["key"] as String?
1006-
query = when (value) {
1007-
is Boolean -> if (key == null) query.endBefore(value) else query.endBefore(value, key)
1008-
is Number -> if (key == null) query.endBefore(value.toDouble()) else query.endBefore(value.toDouble(), key)
1009-
else -> if (key == null) query.endBefore(value.toString()) else query.endBefore(value.toString(), key)
1010-
}
1011-
}
1012-
}
1013-
}
1014-
"limit" -> {
1015-
when (modifier["name"] as String) {
1016-
"limitToFirst" -> {
1017-
val value = (modifier["limit"] as Number).toInt()
1018-
query = query.limitToFirst(value)
1019-
}
1020-
"limitToLast" -> {
1021-
val value = (modifier["limit"] as Number).toInt()
1022-
query = query.limitToLast(value)
1023-
}
1024-
}
1025-
}
1026-
}
1027-
}
879+
val query = queryFromModifiers(reference, request.modifiers)
1028880

1029881
// Add keepSynced to the query
1030882
query.keepSynced(request.value ?: false)
@@ -1038,92 +890,7 @@ class FirebaseDatabasePlugin :
1038890
try {
1039891
val database = getDatabaseFromPigeonApp(app)
1040892
val reference = database.getReference(request.path)
1041-
1042-
// Apply query modifiers if any
1043-
var query: com.google.firebase.database.Query = reference
1044-
// Note: no hasOrderModifier needed — Android SDK defaults to PriorityIndex
1045-
// when no orderBy is specified, so cursors work without an explicit orderBy.
1046-
1047-
for (modifier in request.modifiers) {
1048-
when (modifier["type"] as String) {
1049-
"orderBy" -> {
1050-
when (modifier["name"] as String) {
1051-
"orderByChild" -> {
1052-
query = query.orderByChild(modifier["path"] as String)
1053-
}
1054-
"orderByKey" -> {
1055-
query = query.orderByKey()
1056-
}
1057-
"orderByValue" -> {
1058-
query = query.orderByValue()
1059-
}
1060-
"orderByPriority" -> {
1061-
query = query.orderByPriority()
1062-
}
1063-
}
1064-
}
1065-
"cursor" -> {
1066-
when (modifier["name"] as String) {
1067-
"startAt" -> {
1068-
val value = modifier["value"]
1069-
val key = modifier["key"] as String?
1070-
query = when (value) {
1071-
is Boolean -> if (key == null) query.startAt(value) else query.startAt(value, key)
1072-
is Number -> if (key == null) query.startAt(value.toDouble()) else query.startAt(value.toDouble(), key)
1073-
else -> if (key == null) query.startAt(value.toString()) else query.startAt(value.toString(), key)
1074-
}
1075-
}
1076-
"startAfter" -> {
1077-
val value = modifier["value"]
1078-
val key = modifier["key"] as String?
1079-
query = when (value) {
1080-
is Boolean -> if (key == null) query.startAfter(value) else query.startAfter(value, key)
1081-
is Number -> if (key == null) query.startAfter(value.toDouble()) else query.startAfter(value.toDouble(), key)
1082-
else -> if (key == null) query.startAfter(value.toString()) else query.startAfter(value.toString(), key)
1083-
}
1084-
}
1085-
"endAt" -> {
1086-
val value = modifier["value"]
1087-
val key = modifier["key"] as String?
1088-
query = when (value) {
1089-
is Boolean -> if (key == null) query.endAt(value) else query.endAt(value, key)
1090-
is Number -> if (key == null) query.endAt(value.toDouble()) else query.endAt(value.toDouble(), key)
1091-
else -> if (key == null) query.endAt(value.toString()) else query.endAt(value.toString(), key)
1092-
}
1093-
}
1094-
"endBefore" -> {
1095-
val value = modifier["value"]
1096-
val key = modifier["key"] as String?
1097-
query = when (value) {
1098-
is Boolean -> if (key == null) query.endBefore(value) else query.endBefore(value, key)
1099-
is Number -> if (key == null) query.endBefore(value.toDouble()) else query.endBefore(value.toDouble(), key)
1100-
else -> if (key == null) query.endBefore(value.toString()) else query.endBefore(value.toString(), key)
1101-
}
1102-
}
1103-
}
1104-
}
1105-
"limit" -> {
1106-
when (modifier["name"] as String) {
1107-
"limitToFirst" -> {
1108-
val value = when (val limit = modifier["limit"]) {
1109-
is Int -> limit
1110-
is Number -> limit.toInt()
1111-
else -> throw IllegalArgumentException("Invalid limit value: $limit")
1112-
}
1113-
query = query.limitToFirst(value)
1114-
}
1115-
"limitToLast" -> {
1116-
val value = when (val limit = modifier["limit"]) {
1117-
is Int -> limit
1118-
is Number -> limit.toInt()
1119-
else -> throw IllegalArgumentException("Invalid limit value: $limit")
1120-
}
1121-
query = query.limitToLast(value)
1122-
}
1123-
}
1124-
}
1125-
}
1126-
}
893+
val query = queryFromModifiers(reference, request.modifiers)
1127894

1128895
// Get the data
1129896
query.get().addOnCompleteListener { task ->

packages/firebase_database/firebase_database/android/src/main/kotlin/io/flutter/plugins/firebase/database/QueryBuilder.kt

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,12 @@ package io.flutter.plugins.firebase.database
99
import androidx.annotation.NonNull
1010
import com.google.firebase.database.DatabaseReference
1111
import com.google.firebase.database.Query
12-
import java.util.*
1312

1413
class QueryBuilder
1514
@JvmOverloads
1615
constructor(
1716
@NonNull ref: DatabaseReference,
18-
@NonNull private val modifiers: List<Map<String, Any>>,
17+
@NonNull private val modifiers: List<Map<String, Any?>>,
1918
) {
2019
private var query: Query = ref
2120

@@ -35,9 +34,14 @@ class QueryBuilder
3534
return query
3635
}
3736

38-
private fun limit(modifier: Map<String, Any>) {
37+
private fun limit(modifier: Map<String, Any?>) {
3938
val name = modifier["name"] as String
40-
val value = modifier["limit"] as Int
39+
val value =
40+
when (val limit = modifier["limit"]) {
41+
is Int -> limit
42+
is Number -> limit.toInt()
43+
else -> throw IllegalArgumentException("Invalid limit value: $limit")
44+
}
4145

4246
query =
4347
when (name) {
@@ -47,7 +51,7 @@ class QueryBuilder
4751
}
4852
}
4953

50-
private fun orderBy(modifier: Map<String, Any>) {
54+
private fun orderBy(modifier: Map<String, Any?>) {
5155
val name = modifier["name"] as String
5256

5357
query =
@@ -63,7 +67,7 @@ class QueryBuilder
6367
}
6468
}
6569

66-
private fun cursor(modifier: Map<String, Any>) {
70+
private fun cursor(modifier: Map<String, Any?>) {
6771
val name = modifier["name"] as String
6872

6973
when (name) {
@@ -74,51 +78,51 @@ class QueryBuilder
7478
}
7579
}
7680

77-
private fun startAt(modifier: Map<String, Any>) {
81+
private fun startAt(modifier: Map<String, Any?>) {
7882
val value = modifier["value"]
7983
val key = modifier["key"] as String?
8084

8185
query =
8286
when (value) {
8387
is Boolean -> if (key == null) query.startAt(value) else query.startAt(value, key)
8488
is Number -> if (key == null) query.startAt(value.toDouble()) else query.startAt(value.toDouble(), key)
85-
else -> if (key == null) query.startAt(value as String) else query.startAt(value as String, key)
89+
else -> if (key == null) query.startAt(value.toString()) else query.startAt(value.toString(), key)
8690
}
8791
}
8892

89-
private fun startAfter(modifier: Map<String, Any>) {
93+
private fun startAfter(modifier: Map<String, Any?>) {
9094
val value = modifier["value"]
9195
val key = modifier["key"] as String?
9296

9397
query =
9498
when (value) {
9599
is Boolean -> if (key == null) query.startAfter(value) else query.startAfter(value, key)
96100
is Number -> if (key == null) query.startAfter(value.toDouble()) else query.startAfter(value.toDouble(), key)
97-
else -> if (key == null) query.startAfter(value as String) else query.startAfter(value as String, key)
101+
else -> if (key == null) query.startAfter(value.toString()) else query.startAfter(value.toString(), key)
98102
}
99103
}
100104

101-
private fun endAt(modifier: Map<String, Any>) {
105+
private fun endAt(modifier: Map<String, Any?>) {
102106
val value = modifier["value"]
103107
val key = modifier["key"] as String?
104108

105109
query =
106110
when (value) {
107111
is Boolean -> if (key == null) query.endAt(value) else query.endAt(value, key)
108112
is Number -> if (key == null) query.endAt(value.toDouble()) else query.endAt(value.toDouble(), key)
109-
else -> if (key == null) query.endAt(value as String) else query.endAt(value as String, key)
113+
else -> if (key == null) query.endAt(value.toString()) else query.endAt(value.toString(), key)
110114
}
111115
}
112116

113-
private fun endBefore(modifier: Map<String, Any>) {
117+
private fun endBefore(modifier: Map<String, Any?>) {
114118
val value = modifier["value"]
115119
val key = modifier["key"] as String?
116120

117121
query =
118122
when (value) {
119123
is Boolean -> if (key == null) query.endBefore(value) else query.endBefore(value, key)
120124
is Number -> if (key == null) query.endBefore(value.toDouble()) else query.endBefore(value.toDouble(), key)
121-
else -> if (key == null) query.endBefore(value as String) else query.endBefore(value as String, key)
125+
else -> if (key == null) query.endBefore(value.toString()) else query.endBefore(value.toString(), key)
122126
}
123127
}
124128
}

0 commit comments

Comments
 (0)