Function to output HTML and store the result in firebase hosting - firebase

I want to respond to Firebase events to generate (keep updated) to generate HTML pages and put them to Firebase Hosting so that they can be immediately available for use. I have it working except for the part about uploading the resulting HTML to Firebase hosting. It seems like I cannot do it this way but I want to so that all the pages are pre-rendered and ready to load fast.
I have cloud functions connected to hosting but that is the same old way of fetching from the database during a request cycle which I wanted to avoid.
On this page it says "Prerender your single-page apps to improve SEO." and thats what I want. Is it possible? How to store the pre-rendered pages from a HTTP function?

The "Prerender your single-page apps to improve SEO." talked about on that page is prerender in the cloud before serving the content to the requesting party. It is not generate static files when data updates before a request is even made.Generally the prerendering with appropriate caching headers is enough for most use-cases.
If you really want to pregenerate all the pages whenever data changes, you could do that but that'll be more complicated. There are some good articles and guides about deploying to Firebase Hosting after continuous integration finishes. The general idea holds true for what it sounds like you want except what triggers the build/deploy is data driven rather than code change.

The way to pre-render HTML so that metadata such as JSON-LD is available to search engines and opengraph is available to social media platforms for rich cards in shared links is to use Cloud Functions. You basically run Express/Pug (previously Jade) in your cloud function(s) to respond with HTML after whatever database/datastore lookups have completed. I've implemented this and it works great.
Call functions via HTTP requests provides some direction. You basically add some forwarding info to customize your hosting. This will direct HTTP calls over to your Express server running in Cloud Functions. Check the firebase functions github repo for sample code.

Related

REST authorization with no user concept

Is there any way to do some kind of authorization that allows only people who recently requested a page from Firebase Hosting to be able to send an HTTP POST request to a Firestore db and have it go through?
My page is basically an HTML form that posts data to a Firestore page, though it would be nice if at least one had to speak with the server beforehand, as people do not have to log in to post information.
[EDIT]
Requirements:
Serve a static HTML form (with some Javascript included)
The contents of the HTML form should be posted to a firestore database only if the client actually requested a page from the server within a reasonable timeframe
In general, some external code that did not recently request the page should not be able to post data to the database. This is just a minor restriction to mitigate any "attacks" being too easy.
No concept of user or login
All requests should be done through REST as including the Firebase SDK is way too large for this small of a project
With Firebase Hosting, there is no out-of-the-box logging mechanism that would allow detecting if a user has previously requested a page. You need a more "sophisticated" approach.
I can see two possible approaches. (There might be other ones!)
Approach #1 Use two Cloud Functions to:
Serve the page via Firebase Hosting, see Serve dynamic content and host microservices with Cloud Functions
Write to Firestore, after you have verified the user has previously requested a page.
More details:
For the first part, you will not actually serve dynamic content (I understand you plan to serve static pages through Hosting), but because this page is served through a Cloud Function, you will be able to save a unique token (e.g. a Firestore doc ID or any other UUID value) in, for example, Firestore, before sending back the page content.
Then, for the second part (writing to Firestore), the Cloud Function will first check that there is a document with the doc ID previously generated in the Firestore database, and if it is the case, will allow the write to the database (from the Cloud Function).
So, in this case, both Cloud Functions need to be HTTPS ones. You may be interested by this article which details the drawbacks of writing to Firestore through a CF.
Approach #2 Use Firestore security rules for the check before writing.
Do the same than the previous solution for serving the static pages;
Write directly to Firestore and implement a security rule that checks for the existence of a Firestore document with the doc ID saved in point 1. See the exists method.

Firebase Security Problem? Ninja reaction game with Vue.js + Firebase

The problem
I am following a Vue.js 3 tutorial on youtube and I tried to implement the app shown in this video.
Then I started improving it a bit at a time. You can view my project here.
One of the main features I am trying to add is a Hall of Fame component in which you can view the best ten scores of anyone who plays. You can submit your score just after finishing the game. I decided to use Firestore to hold the data.
However, suppose I build the app for production and host it in a server. Then, I can download the whole project on my laptop, change a little bit the logic, and then play it locally on my computer. That way, I can send any type of data to my firestore database (because my credentials are injected in the javascript by Vue). I can then just send the ideal score of 1 ms to hack the game (this is indeed what a friend of mine managed to do).
The question(s)
The question is: how can I prevent this from happening?
Should I make a few changes in the code about the firebase configuration?
Should I use some other way to store the data, and not firestore?
Should I config properly the firestore security rules?
Also, what are the best security practices in JS frameworks like Vue.js (or React, in general) to prevent the insertion of non-wanted data on the client side? How do I manage the connection to a cloud database from such front-end frameworks?
Disclaimer
I learn everything about programming on my own, by watching youtube videos or googling and so on. I am new not only to Vue and Firebase, but to web development in general. Please consider this when answering.
TL;DR;
If the score is calculated on client-side (in browser) you can't secure it.
Anyone can just see the API call being made from the app to the server and replicate that with rest API tool like postman, so you wouldn't even need to download it locally to make changes.
If your game relies on client-side as a source of data, there is no way for the server to ensure that it is un-tampered.
You can try obfuscating the source code and doing client-side data encription, but it's all in javascript so everything is readable.
If you were to implement it in a more secure way, you would have the server trigger an action (as opposed to the script) but then the times would end up being longer because of the data turn-around time. Since the event fired from server to client and back would be reflected, but even then the automated response can be hacked by handling it with a script.

Is there a way to disable these additional Cloud Function resources from loading?

Sorry, I'm just getting started with Cloud Functions so excuse me if this doesn't make sense.
I noticed when watching the 'Node.js apps on Firebase Hosting' video that each load was only returning the document in question. However I set up my cloud function and noticed that it is also loading some other resources like a favicon?
My cloud function is making a call to an external api and then returning it to the user. All I need is the json body from the response. Do I need these other resources?
A browser is always going to request favicon.ico. That's how it determines what icon to show for the site in the title. It's harmless. There might be some way to disable that for whatever browser you're using, but I don't think it's worthwhile to worry about it.

Firestore cloud functions accept multipart/form-data?

Someone knows if the firestore cloud functions http requests support multipart/form-data, I'm trying to send images to cloudinary through this with help of express and multer, for the moment it doesn't works to me, except if I run it locally
Please consult the documentation for Cloud Functions with respect to the handling of various types of input. It has custom handlers for a few content types.
In particular, look at the section on handling multipart form uploads. You won't be able to apply middleware (such as multer) that automatically deals with that type. You'll have to parse req.rawBody yourself. The code in that section shows how to use another module called busboy to handle things.
Unfortunately, the local emulator doesn't have all these special handlers in place yet, so your code running locally doesn't fully emulate the Cloud Functions environment. Feel free to file a bug request for that and add your voice to others who are experiencing the same.

Can I fire a cloud function from Firebase Hosting after the page has loaded?

I'd like to create a website hosted by Firebase Hosting, which can post/put/get data from a Firebase Database. Google's example to connect Hosting to a Database isn't very helpful to me though, because it doesn't give any indication of how to fire a cloud function AFTER the page has loaded (the example fires a cloud function whenever you go to a specific url and fires when that page loads).
The most similar SO post I could find was this one, which appears to be able to interact with a database after the page loads like I want, my difference is that I want the interaction to be server-side (I want as little information about how the data is stored as possible to be shown).
I'm thinking if I can fire a cloud function after the page has loaded (when a user hit's a save button), that cloud function can interact with the database through an API to save the information.
In my searching I couldn't find very much information about connecting Firebase like this, is this possible/logical?
It sounds like all you need to do is create an HTTP trigger, then call that from a XMLHTTPRequest or similar. You can do that whenever you want from the page that's currently showing in the browser.
Cloud Functions code don't need to be interacting with the database via a REST interface. They should just be using the Admin SDK instead, which is far easier and faster. There are a lot of official samples that illustrate this.

Resources