Firebase Cloud Functions Change Timeout

2020-02-28 06:36发布

问题:

I'm using Firebase Cloud Functions library on Android, and using getHttpsCallable to call a cloud function.

The problem is that the function needs 10-15 seconds to return the result back to the client, so the client throws an exception java.net.SocketTimeoutException: timeout.

Code

    // Create the arguments to the callable function.
    Map<String, Object> data = new HashMap<>();
    data.put("info", info);
    mFunctions.getHttpsCallable(function)
            .call(data)
            .continueWith(new Continuation<HttpsCallableResult, String>() {
                @Override
                public String then(@NonNull Task<HttpsCallableResult> task) {
                    // This continuation runs on either success or failure, but if the task
                    // has failed then getResult() will throw an Exception which will be
                    // propagated down.
                    if (task.isSuccessful()) {
                        String result = (String) task.getResult().getData();
                        Log.v(Constants.LOG_TAG, result);
                        return result;
                    } else {
                        // The condition never was true, always logs the exception.
                        Exception e = task.getException();
                        Log.e(Constants.LOG_TAG, "Failed to join multiplayer room.", e);
                        return null;
                    }
                }
            });

How can I change the timeout so the client would wait more before throwing the exception?

Note. I'm not using OkHttp, Retrofit or the default system Networking functions, I'm using Firebase Cloud Functions library (getHttpsCallable) to call the function.

回答1:

firebase-functions version 16.3.0, released 15 Mar 2019, adds the ability to configure the timeout.



回答2:

I had same issue, so I called https functions with OkHttp instead of getHttpsCallable as a workaround.
The protocol of https.onCall is public.
https://firebase.google.com/docs/functions/callable

The code of calling https functions with OkHttp is here.
https://github.com/ryuta46/firebase-callable-okhttp/blob/56adc5e29a35bdb3b355c14d734e6145da4b6809/android/app/src/main/java/com/ttechsoft/okhttp_callable/MainActivity.kt#L184-L239

Editied.

The code of essential part is below.

    private fun callWithOkHttp(functionName: String) {
        val idToken = idToken ?: return
        val instanceId = instanceId ?: return
        val projectId = FirebaseApp.getInstance()?.options?.projectId ?: return
        val url = "https://us-central1-$projectId.cloudfunctions.net/$functionName"


        val jsonData = JSONObject()
        jsonData.put("text", "inputText")


        val json = JSONObject()
        json.put("data", jsonData)

        val requestBody = RequestBody.create(JSON, json.toString())

        val request = Request.Builder()
            .url(url)
            .post(requestBody)
            .addHeader("Authorization", "Bearer $idToken")
            .addHeader("Firebase-Instance-ID-Token", instanceId)
            .build()


        val okHttpClient = OkHttpClient.Builder()
            .connectTimeout(1 , TimeUnit.MINUTES)
            .readTimeout(1, TimeUnit.MINUTES)
            .writeTimeout(1, TimeUnit.MINUTES)
            .build()

        Log.i(TAG, "Start Okhttp")
        okHttpClient.newCall(request).enqueue(object : Callback {
            override fun onResponse(call: Call, response: Response) {
                if (!response.isSuccessful) {
                    val message = response.body()?.string() ?: "Network Error"
                    runOnUiThread {
                        textOkHttpResult.text = message
                    }

                    return
                }
                runOnUiThread {
                    textOkHttpResult.text = "OK"
                }

                val responseBody = response.body()
                Log.i(TAG, responseBody?.string())
            }

            override fun onFailure(call: Call, e: IOException) {
                val message = e.message ?: "Unknown Network error"
                runOnUiThread {
                    textOkHttpResult.text = message
                }
            }
        })
    }