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.)
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.
I have a simple Firebase Hosting web application (based on a Vue app) which invokes Firebase Function (Google cloud function):
import firebase from "firebase/app";
import "firebase/functions";
firebase.initializeApp(firebaseConfig);
let functions = firebase.app().functions("us-west4");
let testFunction = functions.httpsCallable("testFunction");
and corresponding functions index.js file:
const functions = require("firebase-functions");
exports.testFunction = functions.region("us-west4").https.onCall(async (data, context) => {
console.log("Very important things here");
return {"response": "data"};
});
From security perspective is it possible to
Allow this invocation only from my domain name (Firebase hosting) myhostedapp.web.app
Check for any kind of authentication (e.g. token) that my JS app provides during the request?
I've tried accessing context.auth property (see docs) buth seems like some kind of service account is required and this cannot be used when called from Firebase hosting web application.
Basically I don't want my function to be publicly accessible (simple invocation via trigger url), so any advice or best practice for securing Firebase Hosting + Functions would be appreciated.
Firebase just released a new feature called App Check that does precisely this: it allows the Cloud Functions in your project to only be invoked from apps that are registered in that project.
For web apps this happens through reCAPTCHA v3, which . Then once you enable enforcement of the check on Cloud Functions, it will reject any requests coming from other sources.
You'll typically want to combine App Check with your current user-based approach, so that you can easily block calls from outside your web app, but also still ensure authenticated users only can make calls that they're authorized for.
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.
Goal
I would like Slack to trigger a Firebase Cloud Function.
Example: A user sends a Slack message, and Firebase Cloud Functions writes part of the message to the Firebase Database.
Tools: Slack API \ Event Subscription, googleapis, nodejs, etc.
Issue
The Slack documentation here describes the challenge response requirement.
Once you receive the event, respond in plaintext with the challenge
attribute value.
However, I'm not sure how to let Firebase know the Slack request is authorized. An HTTP request to Firebase Cloud Functions must include a Firebase ID. I've let googleapis do the work of setting up the Firebase ID, and I don't see a way to alter Slack's initial verification request (if I had an ID to provide)
What's the best way to trigger Firebase with the Slack API?
Getting Slack to verify the Firebase URL is pretty easy.
Solution
Google Firebase Cloud Function
import * as functions from "firebase-functions";
export const helloSlack = functions.https.onRequest((request, response) => {
if (request) {
response.status(200).send(request.body);
} else {
console.log("Request Error...");
throw response.status(500);
}
});
Steps
Deploy your Firebase Cloud Function
Goto https://api.slack.com/apps
Your App > Event Subscriptions > Enable Events
Turn on Events
Enter your Firebase Cloud Functions URL
tl;dr
Slack instructions:
We’ll send HTTP POST requests to [your] URL when events occur. As soon
as you enter a URL, we’ll send a request with a challenge parameter,
and your endpoint must respond with the challenge value.
Cloud Function URL:
https://firebase-slack-adaptor.cloudfunctions.net/helloSlack
To meet the verification challenge, enter your Firebase Cloud Functions URL (example above) in Slack's Request URL field.
Your Firebase Cloud Function should return the body of the Slack request. Slack finds what it needs in request.body and should verify your URL.
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.