Skip to content

Commit 7ec62f2

Browse files
authored
feat(database-ktx): add reified function getValue() to MutableData (#1465)
* feat(database-ktx): add reified function getValue() to MutableData * docs(database-ktx): add reified MutableData.getValue() to FOSDC docs * chore: re-generate api.txt for firebase-database-ktx * test(database-ktx): fix MutableData.getValue() with custom type test
1 parent 0662a9c commit 7ec62f2

File tree

5 files changed

+97
-0
lines changed

5 files changed

+97
-0
lines changed

docs/ktx/database.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,21 @@ val messages: List<Message> = snapshot.getValue(typeIndicator)
8080
val snapshot: DocumentSnapshot = ...
8181
val messages: List<Message> = snapshot.getValue<List<@JvmSuppressWildcards Message>>()
8282
```
83+
84+
### Convert a MutableData to a POJO in a Transaction
85+
86+
**Kotlin**
87+
```kotlin
88+
override fun doTransaction(mutableData: MutableData): Transaction.Result {
89+
val post = mutableData.getValue(Post::class.java)
90+
// ...
91+
}
92+
```
93+
94+
**Kotlin + KTX**
95+
```kotlin
96+
override fun doTransaction(mutableData: MutableData): Transaction.Result {
97+
val post = mutableData.getValue<Post>()
98+
// ...
99+
}
100+
```

firebase-database/ktx/api.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ package com.google.firebase.database.ktx {
88
method @NonNull public static com.google.firebase.database.FirebaseDatabase database(@NonNull com.google.firebase.ktx.Firebase, @NonNull com.google.firebase.FirebaseApp app, @NonNull String url);
99
method @NonNull public static com.google.firebase.database.FirebaseDatabase getDatabase(@NonNull com.google.firebase.ktx.Firebase);
1010
method @Nullable public static inline <reified T> T getValue(@NonNull com.google.firebase.database.DataSnapshot);
11+
method @Nullable public static inline <reified T> T getValue(@NonNull com.google.firebase.database.MutableData);
1112
}
1213

1314
}

firebase-database/ktx/src/main/kotlin/com/google/firebase/database/ktx/Database.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import com.google.firebase.database.GenericTypeIndicator
2121
import com.google.firebase.database.FirebaseDatabase
2222
import com.google.firebase.components.Component
2323
import com.google.firebase.components.ComponentRegistrar
24+
import com.google.firebase.database.MutableData
2425

2526
import com.google.firebase.ktx.Firebase
2627
import com.google.firebase.platforminfo.LibraryVersionComponent
@@ -49,6 +50,16 @@ inline fun <reified T> DataSnapshot.getValue(): T? {
4950
return getValue(object : GenericTypeIndicator<T>() {})
5051
}
5152

53+
/**
54+
* Returns the content of the MutableData converted to a POJO.
55+
*
56+
* Supports generics like List<> or Map<>. Use @JvmSuppressWildcards to force the compiler to
57+
* use the type `T`, and not `? extends T`.
58+
*/
59+
inline fun <reified T> MutableData.getValue(): T? {
60+
return getValue(object : GenericTypeIndicator<T>() {})
61+
}
62+
5263
internal const val LIBRARY_NAME: String = "fire-db-ktx"
5364

5465
/** @suppress */

firebase-database/ktx/src/test/kotlin/com/google/firebase/database/DataSnapshotUtil.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,14 @@ fun createDataSnapshot(data: Any?, db: FirebaseDatabase): DataSnapshot {
2828
val node = NodeUtilities.NodeFromJSON(data)
2929
return DataSnapshot(ref, IndexedNode.from(node))
3030
}
31+
32+
/**
33+
* Creates a custom MutableData.
34+
*
35+
* This method is a workaround that enables the creation of a custom
36+
* MutableData using package-private methods.
37+
*/
38+
fun createMutableData(data: Any?): MutableData {
39+
val node = NodeUtilities.NodeFromJSON(data)
40+
return MutableData(node)
41+
}

firebase-database/ktx/src/test/kotlin/com/google/firebase/database/ktx/DatabaseTests.kt

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import com.google.firebase.FirebaseApp
1919
import com.google.firebase.FirebaseOptions
2020
import com.google.firebase.database.FirebaseDatabase
2121
import com.google.firebase.database.createDataSnapshot
22+
import com.google.firebase.database.createMutableData
2223
import com.google.firebase.database.IgnoreExtraProperties
2324
import com.google.firebase.database.Exclude
2425
import com.google.firebase.ktx.Firebase
@@ -167,6 +168,61 @@ class DataSnapshotTests : BaseTestCase() {
167168
}
168169
}
169170

171+
@RunWith(RobolectricTestRunner::class)
172+
class MutableDataTests : BaseTestCase() {
173+
@Test
174+
fun `reified getValue works with basic types`() {
175+
val data = mapOf(
176+
"name" to "John Doe",
177+
"jersey" to 35L,
178+
"goalkeeper" to false,
179+
"avg_goals_per_game" to 0.35
180+
)
181+
val mutableData = createMutableData(data)
182+
183+
assertThat(mutableData.child("name").getValue<String>()).isEqualTo("John Doe")
184+
assertThat(mutableData.child("jersey").getValue<Long>()).isEqualTo(35L)
185+
assertThat(mutableData.child("goalkeeper").getValue<Boolean>()).isEqualTo(false)
186+
assertThat(mutableData.child("avg_goals_per_game").getValue<Double>()).isEqualTo(0.35)
187+
}
188+
189+
@Test
190+
fun `reified getValue works with maps`() {
191+
val data = mapOf(
192+
"name" to "John Doe",
193+
"jersey" to 35L,
194+
"goalkeeper" to false,
195+
"avg_goals_per_game" to 0.35
196+
)
197+
val mutableData = createMutableData(data)
198+
assertThat(mutableData.getValue<Map<String, Any>>()).isEqualTo(data)
199+
}
200+
201+
@Test
202+
fun `reified getValue works with lists types`() {
203+
val data = listOf(
204+
"George",
205+
"John",
206+
"Paul",
207+
"Ringo"
208+
)
209+
val mutableData = createMutableData(data)
210+
assertThat(mutableData.getValue<List<String>>()).isEqualTo(data)
211+
}
212+
213+
@Test
214+
fun `reified getValue works with custom types`() {
215+
val data = Player(
216+
name = "John Doe",
217+
jersey = 35,
218+
goalkeeper = false,
219+
avg_goals_per_game = 0.35
220+
)
221+
val mutableData = createMutableData(data.toMap())
222+
assertThat(mutableData.getValue<Player>()).isEqualTo(data)
223+
}
224+
}
225+
170226
@RunWith(RobolectricTestRunner::class)
171227
class LibraryVersionTest : BaseTestCase() {
172228
@Test

0 commit comments

Comments
 (0)