-
Notifications
You must be signed in to change notification settings - Fork 12
Firebase Functions
Firebase Functions are used to handle events in a serverless way and to prevent Vendor Lock-in, implementing a Rest API that exposes the Firebase's services we use.
The whole project is based on Firebase. We use Firestore to store informations about the website's page, about the conference's sessions, about the speakers, etc. We use Firebase Auth to allow users to login using their Google or Apple or Facebook (and other providers) account. There are events that can happen, that can lead to some operations that must be done. For example, upon a new user's registration, we need to create a document in Firestore, so we can keep informations on that user and organize them in a GDPR compliant way. This will allow us to easily delete datas when a user requests so.
Firebase Functions' Triggers allow us to fire the execution of our Business Logic when an event occurs, giving us an event-driven capability together with a serverless implementation.
An other important reason why we use Firebase Functions is to encapsulate Business Logic and Platform specific implementations. Hedwig will generate a static version of the site when a Devfest Organizer requests a new deploy. This will trigger a build that will collect informations from a Rest API, in order to generate the static version to deploy. A Devfest Organizer will be able to add/edit contents or to operate on registered users, and these operations must be protected: Hedwig will check that the user performing them has the right claims. For these Use Cases, we want to expose an API, instead of directly depending onto Firebase implementations: the API layer will prevent the vendor lock-in and allow whoever to easily adapt the software to different Platforms.
Functions must be written in Typescript. Please, always provide unit tests for complex business logic and for the whole single Function.
Inside of the project, you will see a structure similar to the following one:
/
├── functions/
│ └── src/
│ │ └── api/
│ │ │ └── auth/
│ │ │ │ └── on-create.ts
│ │ │ └── http/
│ │ │ │ └── api.ts
│ │ └── model/
│ │ │ └── user.ts
│ │ └── service/
│ │ │ └── on-user-creation.ts
│ │ └── index.ts
│ └── test/
│ │ └── index.test.ts
│ └── package.json
│ └── pnpm-lock.yaml
│ └── tsconfig.json
└── .firebaserc
└── firebase.json
.firebaserc
will contain informations on the default firebase project. This will not impact the deployment phase, because it uses Github variables to select the project where to deploy the Functions. Though, it will affect manual deployments.
firebase.json
contains configurations on the Firebase's services used and where the source code is placed. You won't need to edit this file.
functions/package.json
contains scripts and dependencies used by the Functions. You will have to perform commands such as pnpm i whatever --save
from the functions
directory, because the Functions' dependencies must be saved in this package.json
.
The Functions' source code is placed in functions/src
. In this directory, you will use:
- the
api
directory to export the Firebase Functions. Every Function will be exported from inside a sub-directory that represent the trigger that will be used. For example, you will put theon-create.ts
file in theapi/auth
directory to export a function that will be triggered upon the creation of a new user in Firebase Auth. The source code in this section will export anything needed by the specific export of the single Function, and will call the business logic that will be placed in theservice
directory. There will be only one Function for the Rest API, and it is the one exported inapi/http/api.ts
. To add new endpoints you will need to edit this file; - the
model
directory for all the models needed by the Functions; - the
service
directory for the Business Logic. This is where you can put middleware or any business logic that maps a specific use case; - the
index.ts
file contains the exports that will be used by the deploy script. When you add a new Function, please, import it in this file and be sure to add it to the exports.
Functions must be tested using the official guidelines. Please, add a Function unit test for each Function you will add. Use the offline testing mode: even if it is not the recommended one, it is easier to test them offline when a PR is being automatically checked.
Always use the Firebase v9+ modular API and only create gen2 Functions.
We use Fastify for the Rest API. Please, when editing api/http/api.ts
, be sure to use Fastify's best practices and use the framework to map new endpoints. Feel free to add any Fastify's plugin if you need to implement checks or any other functionality.