@@ -3,6 +3,9 @@ import com.google.firebase.database.DataSnapshot
3
3
import com.google.firebase.database.DatabaseError
4
4
import com.google.firebase.database.DatabaseReference
5
5
import com.google.firebase.database.ValueEventListener
6
+ import kotlinx.coroutines.experimental.cancel
7
+ import kotlinx.coroutines.experimental.disposeOnCompletion
8
+ import kotlinx.coroutines.experimental.suspendCancellableCoroutine
6
9
import kotlin.coroutines.experimental.suspendCoroutine
7
10
8
11
/* *
@@ -12,7 +15,8 @@ import kotlin.coroutines.experimental.suspendCoroutine
12
15
* main coroutine code that reads a single value from Firebase Database. To use it's functionality
13
16
* call [readValue] function.
14
17
*
15
- * The implementation consists of a [suspendCoroutine] that encapsulates a [ValueEventListener].
18
+ * The implementation consists of a [suspendCancellableCoroutine] that encapsulates a
19
+ * [ValueEventListener].
16
20
*
17
21
* @param reference The Firebase Database node to be read.
18
22
* @param type Expected type wrapped in a Class instance.
@@ -22,8 +26,8 @@ import kotlin.coroutines.experimental.suspendCoroutine
22
26
suspend fun <T : Any > readReference (
23
27
reference : DatabaseReference ,
24
28
type : Class <T >
25
- ): T = suspendCoroutine { continuation ->
26
- reference.addListenerForSingleValueEvent( object : ValueEventListener {
29
+ ): T = suspendCancellableCoroutine { continuation ->
30
+ val listener = object : ValueEventListener {
27
31
28
32
/* *
29
33
* Callback to handle Firebase Database errors
@@ -62,7 +66,11 @@ suspend fun <T : Any> readReference(
62
66
continuation.resumeWithException(exception)
63
67
}
64
68
}
65
- })
69
+ }
70
+
71
+ continuation.invokeOnCompletion { reference.removeEventListener(listener) }
72
+
73
+ reference.addListenerForSingleValueEvent(listener)
66
74
}
67
75
68
76
/* *
@@ -109,7 +117,8 @@ suspend inline fun <reified T : Any> DatabaseReference.readValue(): T = readValu
109
117
* main coroutine code that reads a collection of values from Firebase Database. To use it's
110
118
* functionality call [readValue] function.
111
119
*
112
- * The implementation consists of a [suspendCoroutine] that encapsulates a [ValueEventListener].
120
+ * The implementation consists of a [suspendCancellableCoroutine] that encapsulates a
121
+ * [ValueEventListener].
113
122
*
114
123
* @param reference The Firebase Database node to be read.
115
124
* @param type Expected type wrapped in a Class instance.
@@ -119,8 +128,8 @@ suspend inline fun <reified T : Any> DatabaseReference.readValue(): T = readValu
119
128
suspend fun <T : Any > readReferences (
120
129
reference : DatabaseReference ,
121
130
type : Class <T >
122
- ): Collection <T > = suspendCoroutine { continuation ->
123
- reference.addListenerForSingleValueEvent( object : ValueEventListener {
131
+ ): Collection <T > = suspendCancellableCoroutine { continuation ->
132
+ val listener = object : ValueEventListener {
124
133
125
134
/* *
126
135
* Callback to handle Firebase Database errors
@@ -159,7 +168,11 @@ suspend fun <T : Any> readReferences(
159
168
continuation.resumeWithException(exception)
160
169
}
161
170
}
162
- })
171
+ }
172
+
173
+ continuation.invokeOnCompletion { reference.removeEventListener(listener) }
174
+
175
+ reference.addListenerForSingleValueEvent(listener)
163
176
}
164
177
165
178
/* *
0 commit comments