Google Cloud Platform - Firebase
Created: 2020-03-23 11:15:49 -0700 Modified: 2020-04-25 12:20:31 -0700
Google Cloud Platform
Section titled Google Cloud PlatformBasics
Section titled Basics- If you’re coming from AWS, Google has their own comparison of offerings, e.g. if you want to know that Amazon’s S3 maps to Google Cloud Storage
- All resources are split into regions (like “us-west1”) and then zones (“us-west1-a”, “us-west1-b”, etc.). Some resources will be region-specific, and some will be zonal. I picked nam5 (a multi-region for us-central) for my testing since us-west2 gave me a warning about not supporting Cloud Functions or something.
- The concept of a serverless application seems to be thoroughly considered on GCP. Cloud Firestore has granular read/write security rules to the point where you can have users directly interacting with it. Authentication is built in to Firebase, so users can directly access other services like lambda functions, storage, etc. At each point, GCP is doing the authentication/validation that a typical server would be doing in a non-serverless system, so the same concepts are generally there, but the paradigm of users directly accessing resources is fleshed out.
Pricing
Section titled Pricing- You can set budgets that will email you when a certain amount is spent, but those budgets can’t actually limit the underlying spending (reference). If you want spending to stop, you have to make a Cloud Function that gets triggered on billing metrics or something (i.e. it’s possible to do but I didn’t look into it).
Firebase
Section titled FirebaseBasics
Section titled Basics- GCP
- Every Firebase project is also a Google Cloud Platform project, so you can use all of the GCP features from Firebase (reference).
- Aliases
- Until emulation is better, it’s highly advised that you make two projects: a development version and a production version. Then, manage them with project aliases (reference) (AKA “firebase use”). I suggest setting your “dev” version to the default so that you don’t accidentally override production functions when you deploy from a new terminal. Here’s a simple .firebaserc:
- Access
- Cloud Functions for Firebase, for example, are accessible by anybody with your apiKey. That apiKey is typically public in the case of production websites so that client-side JavaScript can call into the functions, otherwise your app wouldn’t work. However, for a development/staging project, you probably want to treat your apiKey as a secret so that you don’t have people modifying those environments. There are many ways to do this, e.g. using dotenv in NPM.
- Project support email (reference)
- If you go to the console → your project → the settings gear → General → Public settings → Support email, you’ll see a dropdown where you can change the email that shows when users authenticate with Google. To populate this dropdown, you need to go to the “Users and permissions” tab in the same spot where you found “General”, then invite a user to your project who has the email that you want to show. I think they need to be considered an “owner” for you to be able to use their email.
- There’s a pricing calculator at the bottom of the pricing page that’s set to use the free limits by default.
- The paid plan actually consumes the free plan before charging you, so if you’re within the limits, you won’t end up spending any money.
- You pay for outbound networking, meaning if you want to hit a Stripe API from your serverless function, that will cost money, but contacting the Firebase database does not cost money (at least not for the network call).
- You are charged for actions you perform through the Firebase Console (reference)
- Firebase has a concept of projects. You’re not charged for these, but you’re charged for their usage. There is apparently a limit, but it seems flexible (reference). Also, projects have their own free usage allocations, meaning if you get 20K writes per day to Firestore, then each project gets that 20K (reference).
- Rate-limiting
- Because you’re charged for every read/write/invocation, it’s possible that malicious users can run up the costs for your servers by just invoking functions repeatedly or reading data through Firestore (or any other number of things). Firebase itself has no built-in way to prevent this. Answers on StackOverflow suggest using a Cloud Function for this, which itself costs money. After tons of searching (the best query was “firebase malicious cost -firebase.google.com”), I found this answer from a Google employee:
Google infra has DDoS and similar protection which would prevent what you’ve described here; we don’t want data centers crumbling because of abusive users. So at the point someone has the facilities to run “billions” of queries, they’re going to run into limitations at the level of our load balancers and network infra. Not to mention that an attack of that breadth would require an intense amount of system resources and be cost prohibitive. If you experience something of this nature, please just reach out to support. It’s not going to be isolated and you’re not expected to handle attacks on our infrastructure. Running this without a host of servers would be time prohibitive—a billion is a big number.
But more realistically, there’s probably some middle ground here where someone quite determined could abuse a small app and rack up a significant cost. If that happens, just reach out to support. (Hint: I created the credit policies; we’ll help)
☼, Kato
- Every time a function is called, it costs money. There is apparently no built-in way to rate-limit usage (although this page came close; it lets you rate-limit reads/writes per user, not invocations).
- You can also use outright disable all function calls from the Overview page on GCP, e.g. if you’re performing maintenance or there’s some kind of exploit that you want to quickly stop.
Firebase administration
Section titled Firebase administrationBasics
Section titled Basics- How to set up a project (this is needed for administrative code, NOT for client-side code):
- yarn global add firebase-tools
- From the project folder: firebase init
Troubleshooting
Section titled TroubleshootingWarning when importing/requiring all of firebase
Section titled Warning when importing/requiring all of firebaseThe warning looks like this:
It looks like you’re using the development build of the Firebase JS SDK.
When deploying Firebase apps to production, it is advisable to only import
the individual SDK components you intend to use.
For the module builds, these are available in the following manner
(replace <PACKAGE> with the name of a component - i.e. auth, database, etc):
CommonJS Modules:
const firebase = require(‘firebase/app’);
require(‘firebase/<PACKAGE>’);
ES Modules:
import firebase from ‘firebase/app’;
import ‘firebase/<PACKAGE>’;
Typescript:
import * as firebase from ‘firebase/app’;
import ‘firebase/<PACKAGE>’;
The solution is to stop importing everything all at once (just like the warning says):
Error: Cloud resource location is not set for this project but the operation you are attempting to perform in Cloud Firestore requires it. Please see this documentation for more details: https://firebase.google.com/docs/projects/locations
Section titled Error: Cloud resource location is not set for this project but the operation you are attempting to perform in Cloud Firestore requires it. Please see this documentation for more details: https://firebase.google.com/docs/projects/locationsThis error shows from “firebase init” when making a new project at the same time that you initialize. To fix this, go to the Firebase console → your project → Settings → General → GCP resource location → edit: