I've created a cloud functions in firebase and I want to get response of the functions back to Android app.
Cloud functions is written in typescript and is like
exports.validateOtp = functions.https.onRequest((req,res)=>{
phoneNumber = req.query.phoneNumber;
otp = req.query.otp;
getVal();
function getVal(){
let result = authFunction.userValidation(phoneNumber,otp).then(function(boolResult){
return res.status(204).send(result);
});
}
});
How can I fetch the value of result at client side or android app?
Since your Cloud Function is an HTTPS one it will be triggered when you send an HTTP request (GET, POST, PUT, DELETE and OPTIONS) to the function endpoint.
In your case the function endpoint URL will be
https://us-central1-<your-project-id>.cloudfunctions.net/validateOtp
see https://firebase.google.com/docs/functions/http-events#invoke_an_http_function
There are several possible ways to send an HTTP request from an Android app to an HTTP endpoint. You could use the Volley library, the android-async-http library or the Retrofit one, for example.
Note that it may be interesting to switch to an HTTPS Callable Cloud Function instead of a "simple" HTTPS Cloud Function.
As explained in the doc, "the Cloud Functions for Firebase client SDKs let you call functions directly from a Firebase app. To call a function from your app in this way, write and deploy an HTTPS Callable function in Cloud Functions".
Among the advantages offered by HTTPS Callable functions you will find the fact that it "automatically deserializes the request body", that it "validates auth tokens" as well as the fact that you don't need to use an extra library to call the Function, but just to use the code detailed in the doc.
Related
I'm looking into porting a unity game with a dotnet backend over to firebase firestore / functions, etc. My initial tests look promising, but my biggest hold-up is that I would need to rewrite a lot of the server-side logic in JavaScript.
I know that firebase's functions and firestore both run on google cloud, and the cloud version of functions supports a number of additional languages, including c#. I was able to create a couple of C# test functions and upload them to the same project as my unity test. They show up in the firebase portal and can be called via the HTTP endpoints supplied by google cloud, etc.
I discovered that I can call the function that does not require auth using the FirebaseFunctions callabale API in unity (fun fact, it only seems to work if the response is a JSON object in the form of { "result": [data here] }) I cannot, however, call the version of the same function that does require authentication - it returns an internal error message.
I am wondering there is a way to make these methods callable from the unity firebase API - passing in the user id/auth that I get from logging into firebase? I've seen some examples/answers where people say to call the cloud function directly using the Authorization: bearer token header, but I cannot seem to find a way to get the auth token from the current user in the Unity Firebase API.
I imagine that I am stepping further outside the realm of firebase unity API and more into google cloud/identity platform
You can retrieve the ID token of the current user by calling TokenAsync() on their profile.
That's the value you need to pass along in the Authorization header of the call to Cloud Functions, where you can then access it in you Callable Cloud Function.
Alternatively you can implement a regular HTTP Cloud Function, pass the same in whatever way you see fit there, and then on the server decode and verify the ID token with the Admin SDK yourself.
Firebase callable cloud functions can be accessed via client sdks, which requires a valid auth context for authentication and authorization. But and at the same time it is exposed as an HTTP endpoint, thus can be called but will receive an unauthorized response.
My questions is, is there a way to completely restrict public access for a callable cloud functions? since firebase will charge cloud functions based on function executions. Even to return an unauthorized response, the request has already gone through to the function, thus during a DDoS attack this could be problematic.
There is no built-in support for rejecting a request to a Cloud Function before it reaches your code. If you want such functionality consider setting up Cloud Endpoints in front of your Cloud Functions.
The best you can with just Cloud Functions do is check whether the caller is authorized as the first thing in your function code, so that you reduce the amount of time the function is active. You'll still be charged for the invocation in that case, but you'll minimize the GB-seconds and CPU-seconds.
I tried out as #Frank suggested using google cloud run to deploy and ESP container which can by used to invoke private cloud functions. A detailed overview is described in the documentations itself.
https://cloud.google.com/endpoints/docs/openapi/get-started-cloud-functions#deploy_endpoints_proxy
Above given answer by #Frank van Puffelen is perfect but you can utilize a trik to restrict the access by securing that route. Here is the example,
const functions = require('firebase-functions');
exports.scheduleSampleJob = functions.https.onRequest((req , res) => {
let auth = req.header('Authorization');
if(auth == 'YOUR_API_AUTHORIZATION_KEY'){
// valid Authorization key, process the call
}else{
//send forbidden if Authorization key not valid
return res.status(403).send('Access is Forbidden');
}
});
Now, if you want to call the endpoint, It will require a Authorization header in request having value your secret key.
As firebase cloud function can also be used with firebase-auth, you can create custom logic to allow access to users having auth only and restrict the access for public excluding your app's authentic users.
I have a Firebase Cloud Function setup with ExpressJS which I would like to call call from my app.
I could of course just do an http request but since there is an cloud_firestore package (dart/Flutter) I thought that would be the best way to go, guessing it would handle the authentication for me.
The endpoint is just an express app:
const app = express();
app.post('/message', async function (req:any, res: any) {
...
other code
...
}
In my Flutter app I do:
final HttpsCallable addMessage = new CloudFunctions(region: "us-central1")
.getHttpsCallable(functionName: 'api');
addMessage.call();
This will return a NOT_FOUND error, probably because I have to pass in the path for ExpressJS.
But I have not a clue about how to do that.
The Firebase callable functions client library does not work with arbitrary HTTP endpoints. It's meant to work only with callable functions that you write according to the documentation.
If you have a standard HTTP endpoint, just use a regular HTTP client library for that.
If you want to pass Firebase Auth credentials along with the request, there are some examples of that in the Firebase Admin SDK documentation. (You use the Admin SDK to verify the credentials passed from the client app.)
Firebase callable cloud functions can be accessed via client sdks, which requires a valid auth context for authentication and authorization. But and at the same time it is exposed as an HTTP endpoint, thus can be called but will receive an unauthorized response.
My questions is, is there a way to completely restrict public access for a callable cloud functions? since firebase will charge cloud functions based on function executions. Even to return an unauthorized response, the request has already gone through to the function, thus during a DDoS attack this could be problematic.
There is no built-in support for rejecting a request to a Cloud Function before it reaches your code. If you want such functionality consider setting up Cloud Endpoints in front of your Cloud Functions.
The best you can with just Cloud Functions do is check whether the caller is authorized as the first thing in your function code, so that you reduce the amount of time the function is active. You'll still be charged for the invocation in that case, but you'll minimize the GB-seconds and CPU-seconds.
I tried out as #Frank suggested using google cloud run to deploy and ESP container which can by used to invoke private cloud functions. A detailed overview is described in the documentations itself.
https://cloud.google.com/endpoints/docs/openapi/get-started-cloud-functions#deploy_endpoints_proxy
Above given answer by #Frank van Puffelen is perfect but you can utilize a trik to restrict the access by securing that route. Here is the example,
const functions = require('firebase-functions');
exports.scheduleSampleJob = functions.https.onRequest((req , res) => {
let auth = req.header('Authorization');
if(auth == 'YOUR_API_AUTHORIZATION_KEY'){
// valid Authorization key, process the call
}else{
//send forbidden if Authorization key not valid
return res.status(403).send('Access is Forbidden');
}
});
Now, if you want to call the endpoint, It will require a Authorization header in request having value your secret key.
As firebase cloud function can also be used with firebase-auth, you can create custom logic to allow access to users having auth only and restrict the access for public excluding your app's authentic users.
I want to send an HTTP Request from Android to a cloud function, post some values, then input these values into real time database.
index.js
const functions = require('firebase-functions');
exports.testPost = functions.https.onRequest((req, res) => {
console.log(req.body);
});
How can I accomplish this?
I see three steps in here:
Calling a Cloud Function from Android.
This is the same as calling any other HTTP URL from Android. See
Calling a Cloud Function from Android through Firebase
Parsing parameters from the call in your Cloud Function
A HTTP triggered Cloud Function is really just an Express handler. So parsing the post works the same as for other Express handlers. The Firebase documentation for HTTP functions has some examples and links to other documentation.
Posting to the database from a Cloud Functions
All the samples in the functions-samples repo include the Firebase Admin SDK. This SDK allows you to access many Firebase features, such as the database, from within your function. But there's also an example in this repo.