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
json_abort
: like flask.abort but providejson
response which is compatible with Google API Design.firebase_auth_required
: a python decorator which supportFirebase Authentication
and handleAuthorization: Bearer <token>
request headertest_firebase_function
: actual cloud functions which requireFirebase Authentication
and support protocol specification for https.onCall (compatible with Cloud Functions for Firebase).
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: