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..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 @@ -17,6 +17,8 @@ import androidx.annotation.VisibleForTesting import com.google.android.gms.tasks.Task 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. */ @@ -173,6 +175,49 @@ 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. *