Create Compatible Cloud Functions for Firebase With Python (Callable from Cloud Functions for Firebase client SDK)
April 26, 2019using 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
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, abort
from firebase_admin import auth
from functools import wraps
def 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_required
def 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:
- algo-trading
- algolia
- analytics
- android
- android-ktx
- android-permission
- android-studio
- apps-script
- bash
- binance
- bootstrap
- bootstrapvue
- chartjs
- chrome
- cloud-functions
- coding-interview
- contentresolver
- coroutines
- crashlytics
- crypto
- css
- dagger2
- datastore
- datetime
- docker
- eslint
- firebase
- firebase-auth
- firebase-hosting
- firestore
- firestore-security-rules
- flask
- fontawesome
- fresco
- git
- github
- glide
- godot
- google-app-engine
- google-cloud-storage
- google-colab
- google-drive
- google-maps
- google-places
- google-play
- google-sheets
- gradle
- html
- hugo
- inkscape
- java
- java-time
- javascript
- jetpack-compose
- jetson-nano
- kotlin
- kotlin-serialization
- layout
- lets-encrypt
- lifecycle
- linux
- logging
- lubuntu
- markdown
- mate
- material-design
- matplotlib
- md5
- mongodb
- moshi
- mplfinance
- mysql
- navigation
- nginx
- nodejs
- npm
- nuxtjs
- nvm
- pandas
- payment
- pip
- pwa
- pyenv
- python
- recylerview
- regex
- room
- rxjava
- scoped-storage
- selenium
- social-media
- ssh
- ssl
- static-site-generator
- static-website-hosting
- sublime-text
- ubuntu
- unit-test
- uwsgi
- viewmodel
- viewpager2
- virtualbox
- vue-chartjs
- vue-cli
- vue-router
- vuejs
- vuelidate
- vuepress
- web-development
- web-hosting
- webpack
- windows
- workmanager
- wsl
- yarn