From 91847a3b38aed2abd0d788b4693c5b1734aa0b56 Mon Sep 17 00:00:00 2001 From: rosariopf Date: Fri, 14 Mar 2025 13:14:55 +0000 Subject: [PATCH 1/2] feat(functions): add streamAsFlow() --- firebase-functions/api.txt | 2 + .../firebase-functions.gradle.kts | 2 +- .../google/firebase/functions/StreamTests.kt | 3 +- .../functions/HttpsCallableReference.kt | 46 +++++++++++++++++++ 4 files changed, 50 insertions(+), 3 deletions(-) diff --git a/firebase-functions/api.txt b/firebase-functions/api.txt index 1a12a250b35..34e6823f533 100644 --- a/firebase-functions/api.txt +++ b/firebase-functions/api.txt @@ -86,6 +86,8 @@ package com.google.firebase.functions { method public void setTimeout(long timeout, java.util.concurrent.TimeUnit units); method public org.reactivestreams.Publisher stream(); method public org.reactivestreams.Publisher stream(Object? data = null); + method public kotlinx.coroutines.flow.Flow streamAsFlow(); + method public kotlinx.coroutines.flow.Flow streamAsFlow(Object? data = null); method public com.google.firebase.functions.HttpsCallableReference withTimeout(long timeout, java.util.concurrent.TimeUnit units); property public final long timeout; } diff --git a/firebase-functions/firebase-functions.gradle.kts b/firebase-functions/firebase-functions.gradle.kts index 08a797112b9..38f266c4dc3 100644 --- a/firebase-functions/firebase-functions.gradle.kts +++ b/firebase-functions/firebase-functions.gradle.kts @@ -113,6 +113,7 @@ dependencies { implementation(libs.playservices.base) implementation(libs.playservices.basement) implementation(libs.reactive.streams) + implementation(libs.kotlinx.coroutines.reactive) api(libs.playservices.tasks) @@ -133,7 +134,6 @@ dependencies { androidTestImplementation(libs.truth) androidTestImplementation(libs.androidx.test.runner) androidTestImplementation(libs.androidx.test.junit) - androidTestImplementation(libs.kotlinx.coroutines.reactive) androidTestImplementation(libs.mockito.core) androidTestImplementation(libs.mockito.dexmaker) kapt("com.google.dagger:dagger-android-processor:2.43.2") diff --git a/firebase-functions/src/androidTest/java/com/google/firebase/functions/StreamTests.kt b/firebase-functions/src/androidTest/java/com/google/firebase/functions/StreamTests.kt index e0de5cc2262..fb6017e76d3 100644 --- a/firebase-functions/src/androidTest/java/com/google/firebase/functions/StreamTests.kt +++ b/firebase-functions/src/androidTest/java/com/google/firebase/functions/StreamTests.kt @@ -23,7 +23,6 @@ import com.google.firebase.Firebase import com.google.firebase.initialize import java.util.concurrent.TimeUnit import kotlinx.coroutines.delay -import kotlinx.coroutines.reactive.asFlow import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withTimeout import org.junit.Before @@ -100,7 +99,7 @@ class StreamTests { val messages = mutableListOf() var result: StreamResponse.Result? = null - val flow = function.stream(input).asFlow() + val flow = function.streamAsFlow(input) try { withTimeout(1000) { flow.collect { response -> diff --git a/firebase-functions/src/main/java/com/google/firebase/functions/HttpsCallableReference.kt b/firebase-functions/src/main/java/com/google/firebase/functions/HttpsCallableReference.kt index 215722584ba..c57cf9c2249 100644 --- a/firebase-functions/src/main/java/com/google/firebase/functions/HttpsCallableReference.kt +++ b/firebase-functions/src/main/java/com/google/firebase/functions/HttpsCallableReference.kt @@ -15,6 +15,8 @@ package com.google.firebase.functions import androidx.annotation.VisibleForTesting import com.google.android.gms.tasks.Task +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.reactive.asFlow import java.net.URL import java.util.concurrent.TimeUnit import org.reactivestreams.Publisher @@ -173,6 +175,50 @@ public class HttpsCallableReference { } } + /** + * Streams data to the specified HTTPS endpoint. + * + * The data passed into the trigger can be any of the following types: + * + * * Any primitive type, including null, int, long, float, and boolean. + * * [String] + * * [List][java.util.List], where the contained objects are also one of these types. + * * [Map][java.util.Map], where the values are also one of these types. + * * [org.json.JSONArray] + * * [org.json.JSONObject] + * * [org.json.JSONObject.NULL] + * + * If the returned streamResponse fails, the exception will be one of the following types: + * + * * [java.io.IOException] + * - if the HTTPS request failed to connect. + * * [FirebaseFunctionsException] + * - if the request connected, but the function returned an error. + * + * The request to the Cloud Functions backend made by this method automatically includes a + * Firebase Instance ID token to identify the app instance. If a user is logged in with Firebase + * Auth, an auth token for the user will also be automatically included. + * + * Firebase Instance ID sends data to the Firebase backend periodically to collect information + * regarding the app instance. To stop this, see + * [com.google.firebase.iid.FirebaseInstanceId.deleteInstanceId]. It will resume with a new + * Instance ID the next time you call this method. + * + * @param data Parameters to pass to the endpoint. Defaults to `null` if not provided. + * @return [Flow] that will emit intermediate data, and the final result, as it is generated + * by the function. + * @see org.json.JSONArray + * + * @see org.json.JSONObject + * + * @see java.io.IOException + * + * @see FirebaseFunctionsException + */ + @JvmOverloads + public fun streamAsFlow(data: Any? = null): Flow = + stream(data).asFlow() + /** * Changes the timeout for calls from this instance of Functions. The default is 60 seconds. * From eec98b2084a70bb0d2e31938621227a2005167c2 Mon Sep 17 00:00:00 2001 From: rosariopf Date: Fri, 14 Mar 2025 14:10:48 +0000 Subject: [PATCH 2/2] style: spotless apply --- .../firebase/functions/HttpsCallableReference.kt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/firebase-functions/src/main/java/com/google/firebase/functions/HttpsCallableReference.kt b/firebase-functions/src/main/java/com/google/firebase/functions/HttpsCallableReference.kt index c57cf9c2249..b359780e201 100644 --- a/firebase-functions/src/main/java/com/google/firebase/functions/HttpsCallableReference.kt +++ b/firebase-functions/src/main/java/com/google/firebase/functions/HttpsCallableReference.kt @@ -15,10 +15,10 @@ package com.google.firebase.functions import androidx.annotation.VisibleForTesting import com.google.android.gms.tasks.Task -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.reactive.asFlow import java.net.URL import java.util.concurrent.TimeUnit +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.reactive.asFlow import org.reactivestreams.Publisher /** A reference to a particular Callable HTTPS trigger in Cloud Functions. */ @@ -205,8 +205,8 @@ public class HttpsCallableReference { * Instance ID the next time you call this method. * * @param data Parameters to pass to the endpoint. Defaults to `null` if not provided. - * @return [Flow] that will emit intermediate data, and the final result, as it is generated - * by the function. + * @return [Flow] that will emit intermediate data, and the final result, as it is generated by + * the function. * @see org.json.JSONArray * * @see org.json.JSONObject @@ -216,8 +216,7 @@ public class HttpsCallableReference { * @see FirebaseFunctionsException */ @JvmOverloads - public fun streamAsFlow(data: Any? = null): Flow = - stream(data).asFlow() + public fun streamAsFlow(data: Any? = null): Flow = stream(data).asFlow() /** * Changes the timeout for calls from this instance of Functions. The default is 60 seconds.