diff --git a/firebase-common/src/jsMain/kotlin/dev/gitlive/firebase/externals.kt b/firebase-common/src/jsMain/kotlin/dev/gitlive/firebase/externals.kt index f7953ce69..53b46fcc2 100644 --- a/firebase-common/src/jsMain/kotlin/dev/gitlive/firebase/externals.kt +++ b/firebase-common/src/jsMain/kotlin/dev/gitlive/firebase/externals.kt @@ -381,6 +381,13 @@ external object firebase { fun orderBy(field: String, direction: Any): Query fun orderBy(field: FieldPath, direction: Any): Query fun startAfter(document: DocumentSnapshot): Query + fun startAfter(vararg fieldValues: Any): Query + fun startAt(document: DocumentSnapshot): Query + fun startAt(vararg fieldValues: Any): Query + fun endBefore(document: DocumentSnapshot): Query + fun endBefore(vararg fieldValues: Any): Query + fun endAt(document: DocumentSnapshot): Query + fun endAt(vararg fieldValues: Any): Query } open class CollectionReference : Query { diff --git a/firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt b/firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt index e5b512770..fbde82667 100644 --- a/firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt +++ b/firebase-firestore/src/androidMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt @@ -369,6 +369,14 @@ actual open class Query(open val android: com.google.firebase.firestore.Query) { internal actual fun _orderBy(field: FieldPath, direction: Direction) = Query(android.orderBy(field.android, direction)) internal actual fun _startAfter(document: DocumentSnapshot) = Query(android.startAfter(document.android)) + internal actual fun _startAfter(vararg fieldValues: Any) = Query(android.startAfter(*fieldValues)) + internal actual fun _startAt(document: DocumentSnapshot) = Query(android.startAt(document.android)) + internal actual fun _startAt(vararg fieldValues: Any) = Query(android.startAt(*fieldValues)) + + internal actual fun _endBefore(document: DocumentSnapshot) = Query(android.endBefore(document.android)) + internal actual fun _endBefore(vararg fieldValues: Any) = Query(android.endBefore(*fieldValues)) + internal actual fun _endAt(document: DocumentSnapshot) = Query(android.endAt(document.android)) + internal actual fun _endAt(vararg fieldValues: Any) = Query(android.endAt(*fieldValues)) } actual typealias Direction = com.google.firebase.firestore.Query.Direction diff --git a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt index eb4c05a87..410e23b71 100644 --- a/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt +++ b/firebase-firestore/src/commonMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt @@ -70,6 +70,14 @@ expect open class Query { internal fun _orderBy(field: FieldPath, direction: Direction): Query internal fun _startAfter(document: DocumentSnapshot): Query + internal fun _startAfter(vararg fieldValues: Any): Query + internal fun _startAt(document: DocumentSnapshot): Query + internal fun _startAt(vararg fieldValues: Any): Query + + internal fun _endBefore(document: DocumentSnapshot): Query + internal fun _endBefore(vararg fieldValues: Any): Query + internal fun _endAt(document: DocumentSnapshot): Query + internal fun _endAt(vararg fieldValues: Any): Query } fun Query.where(field: String, equalTo: Any?) = _where(field, equalTo) @@ -85,6 +93,14 @@ fun Query.orderBy(field: String, direction: Direction = Direction.ASCENDING) = _ fun Query.orderBy(field: FieldPath, direction: Direction = Direction.ASCENDING) = _orderBy(field, direction) fun Query.startAfter(document: DocumentSnapshot) = _startAfter(document) +fun Query.startAfter(vararg fieldValues: Any) = _startAfter(*fieldValues) +fun Query.startAt(document: DocumentSnapshot) = _startAt(document) +fun Query.startAt(vararg fieldValues: Any) = _startAt(*fieldValues) + +fun Query.endBefore(document: DocumentSnapshot) = _endBefore(document) +fun Query.endBefore(vararg fieldValues: Any) = _endBefore(*fieldValues) +fun Query.endAt(document: DocumentSnapshot) = _endAt(document) +fun Query.endAt(vararg fieldValues: Any) = _endAt(*fieldValues) expect class WriteBatch { inline fun set(documentRef: DocumentReference, data: T, encodeDefaults: Boolean = true, merge: Boolean = false): WriteBatch diff --git a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt index 8d097df12..4acb10308 100644 --- a/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt +++ b/firebase-firestore/src/commonTest/kotlin/dev/gitlive/firebase/firestore/firestore.kt @@ -239,11 +239,148 @@ class FirebaseFirestoreTest { val lastDocumentSnapshot = firstPage.lastOrNull() assertNotNull(lastDocumentSnapshot) - val secondPage = query.startAfter(lastDocumentSnapshot).limit(2).get().documents // Second 2 results (only one left) + + val secondPage = query.startAfter(lastDocumentSnapshot).get().documents assertEquals(1, secondPage.size) assertEquals("ccc", secondPage[0].get("prop1")) } + @Test + fun testStartAfterFieldValues() = runTest { + setupFirestoreData() + val query = Firebase.firestore + .collection("testFirestoreQuerying") + .orderBy("prop1", Direction.ASCENDING) + + val firstPage = query.get().documents + assertEquals(3, firstPage.size) + assertEquals("aaa", firstPage[0].get("prop1")) + assertEquals("bbb", firstPage[1].get("prop1")) + assertEquals("ccc", firstPage[2].get("prop1")) + + val secondPage = query.startAfter("bbb").get().documents + assertEquals(1, secondPage.size) + assertEquals("ccc", secondPage[0].get("prop1")) + } + + @Test + fun testStartAtDocumentSnapshot() = runTest { + setupFirestoreData() + val query = Firebase.firestore + .collection("testFirestoreQuerying") + .orderBy("prop1", Direction.ASCENDING) + + val firstPage = query.limit(2).get().documents // First 2 results + assertEquals(2, firstPage.size) + assertEquals("aaa", firstPage[0].get("prop1")) + assertEquals("bbb", firstPage[1].get("prop1")) + + val lastDocumentSnapshot = firstPage.lastOrNull() + assertNotNull(lastDocumentSnapshot) + + val secondPage = query.startAt(lastDocumentSnapshot).get().documents + assertEquals(2, secondPage.size) + assertEquals("bbb", secondPage[0].get("prop1")) + assertEquals("ccc", secondPage[1].get("prop1")) + } + + @Test + fun testStartAtFieldValues() = runTest { + setupFirestoreData() + val query = Firebase.firestore + .collection("testFirestoreQuerying") + .orderBy("prop1", Direction.ASCENDING) + + val firstPage = query.get().documents // First 2 results + assertEquals(3, firstPage.size) + assertEquals("aaa", firstPage[0].get("prop1")) + assertEquals("bbb", firstPage[1].get("prop1")) + assertEquals("ccc", firstPage[2].get("prop1")) + + val secondPage = query.startAt("bbb").get().documents + assertEquals(2, secondPage.size) + assertEquals("bbb", secondPage[0].get("prop1")) + assertEquals("ccc", secondPage[1].get("prop1")) + } + + @Test + fun testEndBeforeDocumentSnapshot() = runTest { + setupFirestoreData() + val query = Firebase.firestore + .collection("testFirestoreQuerying") + .orderBy("prop1", Direction.ASCENDING) + + val firstPage = query.limit(2).get().documents // First 2 results + assertEquals(2, firstPage.size) + assertEquals("aaa", firstPage[0].get("prop1")) + assertEquals("bbb", firstPage[1].get("prop1")) + + val lastDocumentSnapshot = firstPage.lastOrNull() + assertNotNull(lastDocumentSnapshot) + + val secondPage = query.endBefore(lastDocumentSnapshot).get().documents + assertEquals(1, secondPage.size) + assertEquals("aaa", secondPage[0].get("prop1")) + } + + @Test + fun testEndBeforeFieldValues() = runTest { + setupFirestoreData() + val query = Firebase.firestore + .collection("testFirestoreQuerying") + .orderBy("prop1", Direction.ASCENDING) + + val firstPage = query.get().documents + assertEquals(3, firstPage.size) + assertEquals("aaa", firstPage[0].get("prop1")) + assertEquals("bbb", firstPage[1].get("prop1")) + assertEquals("ccc", firstPage[2].get("prop1")) + + val secondPage = query.endBefore("bbb").get().documents + assertEquals(1, secondPage.size) + assertEquals("aaa", secondPage[0].get("prop1")) + } + + @Test + fun testEndAtDocumentSnapshot() = runTest { + setupFirestoreData() + val query = Firebase.firestore + .collection("testFirestoreQuerying") + .orderBy("prop1", Direction.ASCENDING) + + val firstPage = query.limit(2).get().documents // First 2 results + assertEquals(2, firstPage.size) + assertEquals("aaa", firstPage[0].get("prop1")) + assertEquals("bbb", firstPage[1].get("prop1")) + + val lastDocumentSnapshot = firstPage.lastOrNull() + assertNotNull(lastDocumentSnapshot) + + val secondPage = query.endAt(lastDocumentSnapshot).get().documents + assertEquals(2, secondPage.size) + assertEquals("aaa", secondPage[0].get("prop1")) + assertEquals("bbb", secondPage[1].get("prop1")) + } + + @Test + fun testEndAtFieldValues() = runTest { + setupFirestoreData() + val query = Firebase.firestore + .collection("testFirestoreQuerying") + .orderBy("prop1", Direction.ASCENDING) + + val firstPage = query.get().documents // First 2 results + assertEquals(3, firstPage.size) + assertEquals("aaa", firstPage[0].get("prop1")) + assertEquals("bbb", firstPage[1].get("prop1")) + assertEquals("ccc", firstPage[2].get("prop1")) + + val secondPage = query.endAt("bbb").get().documents + assertEquals(2, secondPage.size) + assertEquals("aaa", secondPage[0].get("prop1")) + assertEquals("bbb", secondPage[1].get("prop1")) + } + @Test fun testIncrementFieldValue() = runTest { val doc = Firebase.firestore diff --git a/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt b/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt index a5524621f..458b83b71 100644 --- a/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt +++ b/firebase-firestore/src/iosMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt @@ -284,6 +284,14 @@ actual open class Query(open val ios: FIRQuery) { internal actual fun _orderBy(field: FieldPath, direction: Direction) = Query(ios.queryOrderedByFieldPath(field.ios, direction == Direction.DESCENDING)) internal actual fun _startAfter(document: DocumentSnapshot) = Query(ios.queryStartingAfterDocument(document.ios)) + internal actual fun _startAfter(vararg fieldValues: Any) = Query(ios.queryStartingAfterValues(fieldValues.asList())) + internal actual fun _startAt(document: DocumentSnapshot) = Query(ios.queryStartingAtDocument(document.ios)) + internal actual fun _startAt(vararg fieldValues: Any) = Query(ios.queryStartingAtValues(fieldValues.asList())) + + internal actual fun _endBefore(document: DocumentSnapshot) = Query(ios.queryEndingBeforeDocument(document.ios)) + internal actual fun _endBefore(vararg fieldValues: Any) = Query(ios.queryEndingBeforeValues(fieldValues.asList())) + internal actual fun _endAt(document: DocumentSnapshot) = Query(ios.queryEndingAtDocument(document.ios)) + internal actual fun _endAt(vararg fieldValues: Any) = Query(ios.queryEndingAtValues(fieldValues.asList())) } @Suppress("UNCHECKED_CAST") diff --git a/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt b/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt index 9cc6dd75e..7f11641b9 100644 --- a/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt +++ b/firebase-firestore/src/jsMain/kotlin/dev/gitlive/firebase/firestore/firestore.kt @@ -332,9 +332,21 @@ actual open class Query(open val js: firebase.firestore.Query) { Query(js.orderBy(field.js, direction.jsString)) } - internal actual fun _startAfter(document: DocumentSnapshot) = rethrow { - Query(js.startAfter(document.js)) - } + internal actual fun _startAfter(document: DocumentSnapshot) = rethrow { Query(js.startAfter(document.js)) } + + internal actual fun _startAfter(vararg fieldValues: Any) = rethrow { Query(js.startAfter(*fieldValues)) } + + internal actual fun _startAt(document: DocumentSnapshot) = rethrow { Query(js.startAt(document.js)) } + + internal actual fun _startAt(vararg fieldValues: Any) = rethrow { Query(js.startAt(*fieldValues)) } + + internal actual fun _endBefore(document: DocumentSnapshot) = rethrow { Query(js.endBefore(document.js)) } + + internal actual fun _endBefore(vararg fieldValues: Any) = rethrow { Query(js.endBefore(*fieldValues)) } + + internal actual fun _endAt(document: DocumentSnapshot) = rethrow { Query(js.endAt(document.js)) } + + internal actual fun _endAt(vararg fieldValues: Any) = rethrow { Query(js.endAt(*fieldValues)) } actual val snapshots get() = callbackFlow { val unsubscribe = rethrow {