Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate Functions Kotlin to strict API #6386

Merged
merged 3 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions firebase-functions/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,9 @@ package com.google.firebase.functions {
method public boolean getLimitedUseAppCheckTokens();
method public long getTimeout();
method public void setTimeout(long timeout, @NonNull java.util.concurrent.TimeUnit units);
field @NonNull public static final com.google.firebase.functions.HttpsCallOptions.Companion Companion;
field public final boolean limitedUseAppCheckTokens;
}

public static final class HttpsCallOptions.Companion {
}

public final class HttpsCallableOptions {
method public boolean getLimitedUseAppCheckTokens();
field public final boolean limitedUseAppCheckTokens;
Expand Down
16 changes: 16 additions & 0 deletions firebase-functions/firebase-functions.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

// Copyright 2022 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
Expand Down Expand Up @@ -55,6 +57,20 @@ android {
testOptions.unitTests.isIncludeAndroidResources = true
}

// Enable Kotlin "Explicit API Mode". This causes the Kotlin compiler to fail if any
// classes, methods, or properties have implicit `public` visibility. This check helps
// avoid accidentally leaking elements into the public API, requiring that any public
// element be explicitly declared as `public`.
// https://github.com/Kotlin/KEEP/blob/master/proposals/explicit-api-mode.md
// https://chao2zhang.medium.com/explicit-api-mode-for-kotlin-on-android-b8264fdd76d1
tasks.withType<KotlinCompile>().all {
if (!name.contains("test", ignoreCase = true)) {
if (!kotlinOptions.freeCompilerArgs.contains("-Xexplicit-api=strict")) {
kotlinOptions.freeCompilerArgs += "-Xexplicit-api=strict"
}
}
}

dependencies {
javadocClasspath("org.codehaus.mojo:animal-sniffer-annotations:1.21")
javadocClasspath(libs.autovalue.annotations)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import org.json.JSONException
import org.json.JSONObject

/** FirebaseFunctions lets you call Cloud Functions for Firebase. */
class FirebaseFunctions
public class FirebaseFunctions
@AssistedInject
internal constructor(
context: Context,
Expand Down Expand Up @@ -105,22 +105,25 @@ internal constructor(
}

/** Returns a reference to the callable HTTPS trigger with the given name. */
fun getHttpsCallable(name: String): HttpsCallableReference {
public fun getHttpsCallable(name: String): HttpsCallableReference {
return HttpsCallableReference(this, name, HttpsCallOptions())
}

/** Returns a reference to the callable HTTPS trigger with the provided URL. */
fun getHttpsCallableFromUrl(url: URL): HttpsCallableReference {
public fun getHttpsCallableFromUrl(url: URL): HttpsCallableReference {
return HttpsCallableReference(this, url, HttpsCallOptions())
}

/** Returns a reference to the callable HTTPS trigger with the given name and call options. */
fun getHttpsCallable(name: String, options: HttpsCallableOptions): HttpsCallableReference {
public fun getHttpsCallable(name: String, options: HttpsCallableOptions): HttpsCallableReference {
return HttpsCallableReference(this, name, HttpsCallOptions(options))
}

/** Returns a reference to the callable HTTPS trigger with the provided URL and call options. */
fun getHttpsCallableFromUrl(url: URL, options: HttpsCallableOptions): HttpsCallableReference {
public fun getHttpsCallableFromUrl(
url: URL,
options: HttpsCallableOptions
): HttpsCallableReference {
return HttpsCallableReference(this, url, HttpsCallOptions(options))
}

Expand Down Expand Up @@ -149,7 +152,7 @@ internal constructor(
}

@Deprecated("Use {@link #useEmulator(String, int)} to connect to the emulator. ")
fun useFunctionsEmulator(origin: String) {
public fun useFunctionsEmulator(origin: String) {
Preconditions.checkNotNull(origin, "origin cannot be null")
urlFormat = "$origin/%2\$s/%1\$s/%3\$s"
}
Expand All @@ -162,7 +165,7 @@ internal constructor(
* @param host the emulator host (for example, 10.0.2.2)
* @param port the emulator port (for example, 5001)
*/
fun useEmulator(host: String, port: Int) {
public fun useEmulator(host: String, port: Int) {
emulatorSettings = EmulatedServiceSettings(host, port)
}

Expand Down Expand Up @@ -318,7 +321,7 @@ internal constructor(
return tcs.task
}

companion object {
public companion object {
/** A task that will be resolved once ProviderInstaller has installed what it needs to. */
private val providerInstalled = TaskCompletionSource<Void>()

Expand Down Expand Up @@ -370,7 +373,7 @@ internal constructor(
* `"us-central1"` or `"https://mydomain.com"`.
*/
@JvmStatic
fun getInstance(app: FirebaseApp, regionOrCustomDomain: String): FirebaseFunctions {
public fun getInstance(app: FirebaseApp, regionOrCustomDomain: String): FirebaseFunctions {
Preconditions.checkNotNull(app, "You must call FirebaseApp.initializeApp first.")
Preconditions.checkNotNull(regionOrCustomDomain)
val component = app.get(FunctionsMultiResourceComponent::class.java)
Expand All @@ -384,7 +387,7 @@ internal constructor(
* @param app The app for the Firebase project.
*/
@JvmStatic
fun getInstance(app: FirebaseApp): FirebaseFunctions {
public fun getInstance(app: FirebaseApp): FirebaseFunctions {
return getInstance(app, "us-central1")
}

Expand All @@ -395,13 +398,13 @@ internal constructor(
* `"us-central1"` or `"https://mydomain.com"`.
*/
@JvmStatic
fun getInstance(regionOrCustomDomain: String): FirebaseFunctions {
public fun getInstance(regionOrCustomDomain: String): FirebaseFunctions {
return getInstance(FirebaseApp.getInstance(), regionOrCustomDomain)
}

/** Creates a Cloud Functions client with the default app. */
@JvmStatic
fun getInstance(): FirebaseFunctions {
public fun getInstance(): FirebaseFunctions {
return getInstance(FirebaseApp.getInstance(), "us-central1")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ import org.json.JSONObject
// TODO: This is a copy of FirebaseFirestoreException.
// We should investigate whether we can at least share the Code enum.
/** The class for all Exceptions thrown by FirebaseFunctions. */
class FirebaseFunctionsException : FirebaseException {
public class FirebaseFunctionsException : FirebaseException {
/**
* The set of error status codes that can be returned from a Callable HTTPS tigger. These are the
* canonical error codes for Google APIs, as documented here:
* https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto#L26
*/
enum class Code(private val value: Int) {
public enum class Code(private val value: Int) {
/**
* The operation completed successfully. FirebaseFunctionsException will never have a status of
* OK.
Expand Down Expand Up @@ -105,7 +105,7 @@ class FirebaseFunctionsException : FirebaseException {
/** The request does not have valid authentication credentials for the operation. */
UNAUTHENTICATED(16);

companion object {
public companion object {
// Create the canonical list of Status instances indexed by their code values.
private val STATUS_LIST = buildStatusList()
private fun buildStatusList(): SparseArray<Code> {
Expand All @@ -121,7 +121,7 @@ class FirebaseFunctionsException : FirebaseException {
}

@JvmStatic
fun fromValue(value: Int): Code {
public fun fromValue(value: Int): Code {
return STATUS_LIST[value, UNKNOWN]
}

Expand All @@ -134,7 +134,7 @@ class FirebaseFunctionsException : FirebaseException {
* @return The corresponding Code, or Code.UNKNOWN if none.
*/
@JvmStatic
fun fromHttpStatus(status: Int): Code {
public fun fromHttpStatus(status: Int): Code {
when (status) {
200 -> return OK
400 -> return INVALID_ARGUMENT
Expand All @@ -159,14 +159,14 @@ class FirebaseFunctionsException : FirebaseException {
*
* @return the code for the FirebaseFunctionsException
*/
val code: Code
public val code: Code

/**
* Gets the details object, if one was included in the error response.
*
* @return the object included in the "details" field of the response.
*/
val details: Any?
public val details: Any?

internal constructor(message: String, code: Code, details: Any?) : super(message) {
this.code = code
Expand All @@ -183,7 +183,7 @@ class FirebaseFunctionsException : FirebaseException {
this.details = details
}

companion object {
public companion object {
/**
* Takes an HTTP response and returns the corresponding Exception if any.
*
Expand All @@ -193,7 +193,7 @@ class FirebaseFunctionsException : FirebaseException {
* @return The corresponding Exception, or null if none.
*/
@JvmStatic
fun fromResponse(
public fun fromResponse(
code: Code,
body: String?,
serializer: Serializer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,29 @@ import com.google.firebase.components.ComponentRegistrar
import java.net.URL

/** Returns the [FirebaseFunctions] instance of the default [FirebaseApp]. */
val Firebase.functions: FirebaseFunctions
public val Firebase.functions: FirebaseFunctions
get() = FirebaseFunctions.getInstance()

/** Returns the [FirebaseFunctions] instance of a given [regionOrCustomDomain]. */
fun Firebase.functions(regionOrCustomDomain: String): FirebaseFunctions =
public fun Firebase.functions(regionOrCustomDomain: String): FirebaseFunctions =
FirebaseFunctions.getInstance(regionOrCustomDomain)

/** Returns the [FirebaseFunctions] instance of a given [FirebaseApp]. */
fun Firebase.functions(app: FirebaseApp): FirebaseFunctions = FirebaseFunctions.getInstance(app)
public fun Firebase.functions(app: FirebaseApp): FirebaseFunctions =
FirebaseFunctions.getInstance(app)

/** Returns the [FirebaseFunctions] instance of a given [FirebaseApp] and [regionOrCustomDomain]. */
fun Firebase.functions(app: FirebaseApp, regionOrCustomDomain: String): FirebaseFunctions =
public fun Firebase.functions(app: FirebaseApp, regionOrCustomDomain: String): FirebaseFunctions =
FirebaseFunctions.getInstance(app, regionOrCustomDomain)

/** @suppress */
@Keep
class FirebaseFunctionsKtxRegistrar : ComponentRegistrar {
public class FirebaseFunctionsKtxRegistrar : ComponentRegistrar {
override fun getComponents(): List<Component<*>> = listOf()
}

/** Returns a reference to the Callable HTTPS trigger with the given name and call options. */
fun FirebaseFunctions.getHttpsCallable(
public fun FirebaseFunctions.getHttpsCallable(
name: String,
init: HttpsCallableOptions.Builder.() -> Unit
): HttpsCallableReference {
Expand All @@ -55,7 +56,7 @@ fun FirebaseFunctions.getHttpsCallable(
}

/** Returns a reference to the Callable HTTPS trigger with the given URL and call options. */
fun FirebaseFunctions.getHttpsCallableFromUrl(
public fun FirebaseFunctions.getHttpsCallableFromUrl(
url: URL,
init: HttpsCallableOptions.Builder.() -> Unit
): HttpsCallableReference {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import java.util.concurrent.Executor
* @hide
*/
@Keep
class FunctionsRegistrar : ComponentRegistrar {
public class FunctionsRegistrar : ComponentRegistrar {
override fun getComponents(): List<Component<*>> {
val liteExecutor = Qualified.qualified(Lightweight::class.java, Executor::class.java)
val uiExecutor = Qualified.qualified(UiThread::class.java, Executor::class.java)
Expand Down Expand Up @@ -67,7 +67,7 @@ class FunctionsRegistrar : ComponentRegistrar {
)
}

companion object {
private companion object {
private const val LIBRARY_NAME = "fire-fn"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,22 @@ import java.util.concurrent.TimeUnit
import okhttp3.OkHttpClient

/** An internal class for keeping track of options applied to an HttpsCallableReference. */
class HttpsCallOptions {
public class HttpsCallOptions {
// The timeout to use for calls from references created by this Functions.
private var timeout = DEFAULT_TIMEOUT
private var timeoutUnits = DEFAULT_TIMEOUT_UNITS
@JvmField val limitedUseAppCheckTokens: Boolean
@JvmField public val limitedUseAppCheckTokens: Boolean

/** Creates an (internal) HttpsCallOptions from the (external) [HttpsCallableOptions]. */
constructor(publicCallableOptions: HttpsCallableOptions) {
public constructor(publicCallableOptions: HttpsCallableOptions) {
limitedUseAppCheckTokens = publicCallableOptions.limitedUseAppCheckTokens
}

constructor() {
public constructor() {
limitedUseAppCheckTokens = false
}

fun getLimitedUseAppCheckTokens(): Boolean {
public fun getLimitedUseAppCheckTokens(): Boolean {
return limitedUseAppCheckTokens
}

Expand All @@ -42,7 +42,7 @@ class HttpsCallOptions {
* @param timeout The length of the timeout, in the given units.
* @param units The units for the specified timeout.
*/
fun setTimeout(timeout: Long, units: TimeUnit) {
public fun setTimeout(timeout: Long, units: TimeUnit) {
this.timeout = timeout
timeoutUnits = units
}
Expand All @@ -52,20 +52,20 @@ class HttpsCallOptions {
*
* @return The timeout, in milliseconds.
*/
fun getTimeout(): Long {
public fun getTimeout(): Long {
return timeoutUnits.toMillis(timeout)
}

/** Creates a new OkHttpClient with these options applied to it. */
fun apply(client: OkHttpClient): OkHttpClient {
public fun apply(client: OkHttpClient): OkHttpClient {
return client
.newBuilder()
.callTimeout(timeout, timeoutUnits)
.readTimeout(timeout, timeoutUnits)
.build()
}

companion object {
private companion object {
// The default timeout to use for all calls.
private const val DEFAULT_TIMEOUT: Long = 70
private val DEFAULT_TIMEOUT_UNITS = TimeUnit.SECONDS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,39 +18,39 @@ package com.google.firebase.functions
*
* These properties are immutable once a callable function reference is instantiated.
*/
class HttpsCallableOptions
public class HttpsCallableOptions
private constructor(
/**
* Returns the setting indicating if limited-use App Check tokens are enforced for this function.
*/
// If true, request a limited-use token from AppCheck.
@JvmField val limitedUseAppCheckTokens: Boolean
@JvmField public val limitedUseAppCheckTokens: Boolean
) {

fun getLimitedUseAppCheckTokens(): Boolean {
public fun getLimitedUseAppCheckTokens(): Boolean {
return limitedUseAppCheckTokens
}

/** Builder class for [com.google.firebase.functions.HttpsCallableOptions] */
class Builder {
@JvmField var limitedUseAppCheckTokens = false
public class Builder {
@JvmField public var limitedUseAppCheckTokens: Boolean = false

/** Returns the setting indicating if limited-use App Check tokens are enforced. */
fun getLimitedUseAppCheckTokens(): Boolean {
public fun getLimitedUseAppCheckTokens(): Boolean {
return limitedUseAppCheckTokens
}

/**
* Sets whether or not to use limited-use App Check tokens when invoking the associated
* function.
*/
fun setLimitedUseAppCheckTokens(limitedUse: Boolean): Builder {
public fun setLimitedUseAppCheckTokens(limitedUse: Boolean): Builder {
limitedUseAppCheckTokens = limitedUse
return this
}

/** Builds a new [com.google.firebase.functions.HttpsCallableOptions]. */
fun build(): HttpsCallableOptions {
public fun build(): HttpsCallableOptions {
return HttpsCallableOptions(limitedUseAppCheckTokens)
}
}
Expand Down
Loading
Loading