How do you return data from a back end node js to front end html? - firebase

Im working with Firebase functions. I want to return data from a Node JS cloud function to to be able to use it with html /front end code.
const functions = require("firebase-functions");
// // Create and Deploy Your First Cloud Functions
// // https://firebase.google.com/docs/functions/write-firebase-functions
//
exports.helloWorld = functions.https.onRequest((request, response) => {
functions.logger.info("Hello logs!", {structuredData: true});
response.send("Hello from Firebase!");
});

Keep in mind that not all the Javscript code you have will be in a Cloud Function, code that directly interacts with your front end will still need to be in there, however, any code that directly operates with firebase can be transfered to a Cloud Functions.
You could use either Callable Functions, which can be called directly from your Javascript code but are hosted on the cloud, or HTTP Functions which are basically a HTTP request to an URL that sends you a response when it's done.
Cloud Functions also provides an emulator so you can test everything locally.
Before starting anything thought, I would recommend you to watch this playlist provided by Firebase that gives a really good intruction to Cloud Functions, so exactly what you are looking for.

Related

Is it possible to assert the number of reads/writes in a Firebase Cloud Function test?

I have a test suite that runs integration tests for my Firebase Cloud Functions against a locally running Firebase emulator, is it possible to assert the number of reads/writes made to the emulated Firestore instance?
E.g. for the following function I would want to assert that 1 write occurs & 0 reads
const functions = require("firebase-functions");
const admin = require("firebase-admin");
admin.initializeApp();
exports.addMessage = functions.https.onCall(async (data, context) => {
const original = data.query.text;
const snapshot = await admin.firestore().collection("/messages").add({ original: original });
return { code: 200, message: "Success" };
});
Currently, Its not possible to assert the number of reads and writes in a Firebase Cloud Function test.
I would suggest that the best way would be is to write the test data to the Firebase Emulator, then read it back and also count the number of collections/documents as well using Client SDK.
If you want to assert data coming from the Firebase Emulator, then you can use Requests Monitor. We used Client SDK for this purpose as Admin SDK requests and access calls will not be listed because it bypass Security Rules. It's a current limitation according to this Blog.
The Firebase emulator has a log that shows requests as shown in example below.
Note: I don't think that you should have a dependency on it, since Firebase Emulator Request Monitor is a new feature that its implementation may change and Admin SDK can be included over time.

How to trigger Pub/Sub Topic for Firebase Emulator

Using Firebase Functions, I have code that runs every hour via a Google Cloud Scheduler Job.
It looks like this:
exports.hourly_tick =
functions.pubsub.topic("hourly-tick").onPublish((message, context) => {
return getData()
.then((data) => {
sendEmail(data["message"]);
})
.catch((error) => {
return console.log("🚩 Caught error: ", error);
});
});
I need to be able to test this locally, and am able to start my Firebase Emulator via firebase emulators:start from my terminal. However I do not know how to trigger this function in my local test environment to see logs in the local emulator.
How can I test this scheduled job / firebase function with the local emulator?
This is an ongoing feature request in Firebase tools (see GitHub issue).
As mentioned in the thread:
I think we maybe misled with how we represented #2011. It lets those functions be loaded into the emulator but doesn't actually trigger them on a schedule. Instead you'd have to manually trigger them using a Pub/Sub message.
You can check a workaround on this answer where you'd have to manually trigger a scheduled function using a Pub/Sub message.

Firebase functions logging does not work from non-callable functions

I'm getting started with Firebase Functions. I made a simple callable function:
exports.myCallable = functions.https.onCall((data, context) => {
console.log('I am here.');
functions.logger.log('I am here 2.');
});
As expected, I see these logs in the Logs tab in Firebase Console.
However, I also made this function, which should trigger when the user creates their account.
exports.setGroupAfterAuth = functions.auth.user().onCreate((user) => {
console.log('I am here 3.');
functions.logger.log('I am here 4.');
});
In this case, I see that the function was called in Firebase Console, but I do not see my logs.
Why do the logs appear in Firebase Console for the first function but not the second, and what can I do to make them appear in the second?
It's not possible to use the Firebase Functions client SDK to invoke an auth onCreate function.
Auth onCreate functions can only be invoked by actually creating a new user account. They cannot be invoked directly from your app.
The client SDK can only be used to invoke callable functions, as described in the linked documentation. The funciton must be declared with functions.https.onCall.

Cloud Functions: callback is not a function

According to https://cloud.google.com/functions/docs/writing/background
You use background functions when you want to have your Cloud Function invoked indirectly in response to an event, such as a message on a Cloud Pub/Sub topic, a change in a Cloud Storage bucket, or a Firebase event.
And the function paramaters are (data, context, callback): https://cloud.google.com/functions/docs/writing/background#function_parameters
However, when I write a simple function like
exports = module.exports = functions.firestore
.document(path)
.onWrite((change, context, callback) => {
callback()
return
})
I get an error that says
TypeError: callback is not a function
Is callback not part of Firestore background functions? The documentation says it is
If not, is there anyway to immediately exit a function?
The Firebase API is different than the Google Cloud API. What you linked to was the Cloud API, which accepts a callback parameter. The Firebase API which you are actually using does not. The Firebase API for background functions requires you to return a promise that resolves after all the work is complete. There is no callback to call in that case.

Firebase: Writing Custom Callable Cloud Function vs Cloud Firestore Trigger Function

I learned all about Google Cloud Functions Triggers and I understood that they are good for doing some data preprocessing before write/update/delete happens in Cloud Firestore. This is true right?
However, instead of listening to changes in the database, I would like to write custom code in Cloud Functions and call it directly from the client SDK.
The reason I want to do this is because I don't want to have long complicated database integration logic in my client code. I just want to call a cloud function named createGame for instance and let the custom cloud function handle the nested calls to the Firestore, do sanity checks and return me with only the clean data that the client will be displaying.
I found out that there is a Flutter plugin for this called cloud_functions.
Also this documentation shows how to write custom callable functions.
We can write the custom callable Cloud Function as follows:
exports.createGame = functions.https.onCall((data, context) => {
// ...
return {
...
}
});
We can call the corresponding custom callable Cloud Function from Flutter client as follows:
final dynamic response = await CloudFunctions.instance.call(
functionName: 'createGame',
parameters: <String, dynamic>{
'message': 'hello world!',
'count': clientCount,
},
);
There are tons of Cloud Functions trigger examples/videos/tutorials. But very few of callable Cloud Functions. That's why I am a little skeptic about this subject.
Question:
My question is if this is good practice? Or should I do what this specific Cloud Function is doing from the client? Please answer while keeping pricing, speed, reliability and other factors in mind also:)
One last thing,
The function implementation uses https.onCall. Do you think https is slowing things down?

Resources