Create Compatible Cloud Functions for Firebase With Python (Callable from Cloud Functions for Firebase client SDK)

using Google Cloud Functions

Yes, the terminology is very confusing. Refer to Google Cloud Functions vs Cloud Functions for Firebase (and Cloud Functions for Firebase client SDK).

Cloud Functions for Firebase client SDK is a wrapper client to help to call Cloud Functions for Firebase from iOS/Android/Web. Of course you can write your own http call or use Retrofit, but the client SDK offer convinience plus a few firebase integration like Firebase Authentication.

Officially, Cloud Functions for Firebase can only be coded with JavaScript or TypeScript.

This article will guide you on making Google Cloud Functions compatible with Cloud Functions for Firebase, and making it possible to call Google Cloud Functions using Cloud Functions for Firebase client SDK.

We shall write a cloud function which

  • Firebase Authentication
  • Access a json parameter
  • Return a json response

Code explanation

from flask import jsonify, abortfrom firebase_admin import authfrom functools import wrapsdef json_abort(status_code, message):    data = {        'error': {            'code': status_code,            'message': message        }    }    response = jsonify(data)    response.status_code = status_code    abort(response)def firebase_auth_required(f):    @wraps(f)    def wrapper(request):        authorization = request.headers.get('Authorization')        id_token = None        if authorization and authorization.startswith('Bearer '):            id_token = authorization.split('Bearer ')[1]        else:            json_abort(401, message="Invalid authorization")        try:            decoded_token = auth.verify_id_token(id_token)        except Exception as e: # ValueError or auth.AuthError            json_abort(401, message="Invalid authorization")        return f(request, decoded_token)    return wrapper@firebase_auth_requireddef test_firebase_function(request, decoded_token = None):    data = request.json.get('data')    if 'name' not in data:        json_abort(400, message="Missing name")    name = data['name']    return jsonify({        'data': {            'name': name        }    })

Deploy test_firebase_function cloud functions.

gcloud functions deploy test_firebase_function --runtime python37 --trigger-http --project [PROJECT_ID]

Test call Cloud Functions from Android

Include dependencies.

dependencies {
    implementation 'com.google.firebase:firebase-functions:16.3.0'
}

NOTE: There might be some firebase prerequisites.

Code

fun getFirebaseFunction(): Task<String> {    val functions = FirebaseFunctions.getInstance()    val data = mapOf(        "name" to "Desmond"    )    return functions.getHttpsCallable("test_firebase_function")        .call(data)        .continueWith { task ->            val result = task.result?.data as HashMap<*, *>            result["name"] as String        }}
getFirebaseFunction().addOnCompleteListener { task ->    if (task.isSuccessful) {        val name = task.result        Timber.d("name=$name")    }    else {        Timber.e(task.exception)    }}

References:

❤️ Is this article helpful?

Buy me a coffee ☕ or support my work via PayPal to keep this space 🖖 and ad-free.

Do send some 💖 to @d_luaz or share this article.

✨ By Desmond Lua

A dream boy who enjoys making apps, travelling and making youtube videos. Follow me on @d_luaz

👶 Apps I built

Travelopy - discover travel places in Malaysia, Singapore, Taiwan, Japan.